from ieee754.fpcommon.fpbase import FPNumBase, FPNumBaseRecord
from ieee754.fpcommon.fpbase import FPState
from ieee754.fpcommon.denorm import FPSCData
+from ieee754.fpcommon.getop import FPBaseData
class FPAddStage0Data:
- def __init__(self, width, id_wid):
+ def __init__(self, width, pspec):
self.z = FPNumBaseRecord(width, False)
self.out_do_z = Signal(reset_less=True)
self.oz = Signal(width, reset_less=True)
self.tot = Signal(self.z.m_width + 4, reset_less=True)
- self.mid = Signal(id_wid, reset_less=True)
+ self.ctx = FPBaseData(width, pspec)
+ self.mid = self.ctx.mid
def eq(self, i):
return [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
- self.tot.eq(i.tot), self.mid.eq(i.mid)]
+ self.tot.eq(i.tot), self.ctx.eq(i.ctx)]
class FPAddStage0Mod(Elaboratable):
- def __init__(self, width, id_wid):
+ def __init__(self, width, pspec):
self.width = width
- self.id_wid = id_wid
+ self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPSCData(self.width, self.id_wid)
+ return FPSCData(self.width, self.pspec, True)
def ospec(self):
- return FPAddStage0Data(self.width, self.id_wid)
+ return FPAddStage0Data(self.width, self.pspec)
def process(self, i):
return self.o
m.d.comb += self.o.oz.eq(self.i.oz)
m.d.comb += self.o.out_do_z.eq(self.i.out_do_z)
- m.d.comb += self.o.mid.eq(self.i.mid)
+ m.d.comb += self.o.ctx.eq(self.i.ctx)
return m
give greatest accuracy.
"""
- def __init__(self, width, id_wid):
+ def __init__(self, width, pspec):
FPState.__init__(self, "add_0")
self.mod = FPAddStage0Mod(width)
self.o = self.mod.ospec()
detects when tot sum is too big (tot[27] is kinda a carry bit)
"""
- def __init__(self, width, id_wid):
+ def __init__(self, width, pspec):
self.width = width
- self.id_wid = id_wid
+ self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPAddStage0Data(self.width, self.id_wid)
+ return FPAddStage0Data(self.width, self.pspec)
def ospec(self):
- return FPAddStage1Data(self.width, self.id_wid)
+ return FPAddStage1Data(self.width, self.pspec)
def process(self, i):
return self.o
m.d.comb += self.o.out_do_z.eq(self.i.out_do_z)
m.d.comb += self.o.oz.eq(self.i.oz)
- m.d.comb += self.o.mid.eq(self.i.mid)
+ m.d.comb += self.o.ctx.eq(self.i.ctx)
return m
class FPAddStage1(FPState):
- def __init__(self, width, id_wid):
+ def __init__(self, width, pspec):
FPState.__init__(self, "add_1")
self.mod = FPAddStage1Mod(width)
self.out_z = FPNumBase(width, False)
class FPAddAlignSingleAdd(FPState, SimpleHandshake):
- def __init__(self, width, id_wid):
+ def __init__(self, width, pspec):
FPState.__init__(self, "align")
self.width = width
- self.id_wid = id_wid
+ self.pspec = pspec
SimpleHandshake.__init__(self, self) # pipeline is its own stage
self.a1o = self.ospec()
def ispec(self):
- return FPSCData(self.width, self.id_wid)
+ return FPSCData(self.width, self.pspec, True)
def ospec(self):
- return FPAddStage1Data(self.width, self.id_wid) # AddStage1 ospec
+ return FPAddStage1Data(self.width, self.pspec) # AddStage1 ospec
def setup(self, m, i):
""" links module to inputs and outputs
"""
# chain AddAlignSingle, AddStage0 and AddStage1
- mod = FPAddAlignSingleMod(self.width, self.id_wid)
- a0mod = FPAddStage0Mod(self.width, self.id_wid)
- a1mod = FPAddStage1Mod(self.width, self.id_wid)
+ mod = FPAddAlignSingleMod(self.width, self.pspec)
+ a0mod = FPAddStage0Mod(self.width, self.pspec)
+ a1mod = FPAddStage1Mod(self.width, self.pspec)
chain = StageChain([mod, a0mod, a1mod])
chain.setup(m, i)
from ieee754.fpcommon.fpbase import MultiShiftRMerge
from ieee754.fpcommon.fpbase import FPState
from ieee754.fpcommon.denorm import FPSCData
+from ieee754.fpcommon.getop import FPBaseData
class FPNumIn2Ops:
- def __init__(self, width, id_wid):
+ def __init__(self, width, pspec):
self.a = FPNumBaseRecord(width)
self.b = FPNumBaseRecord(width)
self.z = FPNumBaseRecord(width, False)
self.out_do_z = Signal(reset_less=True)
self.oz = Signal(width, reset_less=True)
- self.mid = Signal(id_wid, reset_less=True)
+ self.ctx = FPBaseData(width, pspec)
+ self.mid = self.ctx.mid
def eq(self, i):
return [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
- self.a.eq(i.a), self.b.eq(i.b), self.mid.eq(i.mid)]
+ self.a.eq(i.a), self.b.eq(i.b), self.ctx.eq(i.ctx)]
class FPAddAlignMulti(FPState):
- def __init__(self, width, id_wid):
+ def __init__(self, width, pspec):
FPState.__init__(self, "align")
- self.mod = FPAddAlignMultiMod(width)
+ self.mod = FPAddAlignMultiMod(width, pspec)
self.out_a = FPNumBaseRecord(width)
self.out_b = FPNumBaseRecord(width)
self.exp_eq = Signal(reset_less=True)
class FPAddAlignSingleMod(Elaboratable):
- def __init__(self, width, id_wid):
+ def __init__(self, width, pspec):
self.width = width
- self.id_wid = id_wid
+ self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPSCData(self.width, self.id_wid)
+ return FPSCData(self.width, self.pspec, True)
def ospec(self):
- return FPNumIn2Ops(self.width, self.id_wid)
+ return FPNumIn2Ops(self.width, self.pspec)
def process(self, i):
return self.o
self.o.a.s.eq(self.i.a.s), # whoops forgot sign
]
- m.d.comb += self.o.mid.eq(self.i.mid)
+ m.d.comb += self.o.ctx.eq(self.i.ctx)
m.d.comb += self.o.z.eq(self.i.z)
m.d.comb += self.o.out_do_z.eq(self.i.out_do_z)
m.d.comb += self.o.oz.eq(self.i.oz)
class FPAddAlignSingle(FPState):
- def __init__(self, width, id_wid):
+ def __init__(self, width, pspec):
FPState.__init__(self, "align")
- self.mod = FPAddAlignSingleMod(width, id_wid)
+ self.mod = FPAddAlignSingleMod(width, pspec)
self.out_a = FPNumIn(None, width)
self.out_b = FPNumIn(None, width)
self.width = width
self.id_wid = num_bits(width)
self.op_wid = op_wid
- self.alu = FPADDBasePipe(width, self.id_wid)
+ self.pspec = {'id_wid': self.id_wid, 'op_wid': op_wid}
+ self.alu = FPADDBasePipe(width, self.pspec)
ReservationStations.__init__(self, num_rows)
def i_specfn(self):
- return FPADDBaseData(self.width, self.id_wid, self.op_wid)
+ return FPADDBaseData(self.width, self.pspec)
def o_specfn(self):
- return FPPackData(self.width, self.id_wid, self.op_wid)
+ return FPPackData(self.width, self.pspec)
https://steve.hollasch.net/cgindex/coding/ieeefloat.html
"""
- def __init__(self, width, id_wid, op_wid=None):
+ def __init__(self, width, pspec):
self.width = width
- self.id_wid = id_wid
- self.op_wid = op_wid
+ self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPADDBaseData(self.width, self.id_wid, self.op_wid)
+ return FPADDBaseData(self.width, self.pspec)
def ospec(self):
- return FPSCData(self.width, self.id_wid, True, self.op_wid)
+ return FPSCData(self.width, self.pspec, True)
def setup(self, m, i):
""" links module to inputs and outputs
m.d.comb += self.o.out_do_z.eq(0)
m.d.comb += self.o.oz.eq(self.o.z.v)
- m.d.comb += self.o.mid.eq(self.i.mid)
- if self.o.op_wid:
- m.d.comb += self.o.op.eq(self.i.op)
+ m.d.comb += self.o.ctx.eq(self.i.ctx)
return m
"""
self.mod.setup(m, i, self.out_do_z)
m.d.sync += self.out_z.v.eq(self.mod.out_z.v) # only take the output
- m.d.sync += self.out_z.mid.eq(self.mod.o.mid) # (and mid)
+ m.d.sync += self.out_z.ctx.eq(self.mod.o.ctx) # (and mid)
def action(self, m):
self.idsync(m)
https://steve.hollasch.net/cgindex/coding/ieeefloat.html
"""
- def __init__(self, width, id_wid, op_wid=None):
+ def __init__(self, width, pspec):
FPState.__init__(self, "special_cases")
self.width = width
- self.id_wid = id_wid
- self.op_wid = op_wid
+ self.pspec = pspec
SimpleHandshake.__init__(self, self) # pipe is its own stage
self.out = self.ospec()
def ispec(self):
- return FPADDBaseData(self.width, self.id_wid, self.op_wid) # SC ispec
+ return FPADDBaseData(self.width, self.pspec) # SC ispec
def ospec(self):
- return FPSCData(self.width, self.id_wid, True, self.op_wid) # DeNorm
+ return FPSCData(self.width, self.pspec, True) # DeNorm
def setup(self, m, i):
""" links module to inputs and outputs
"""
- smod = FPAddSpecialCasesMod(self.width, self.id_wid)
- dmod = FPAddDeNormMod(self.width, self.id_wid)
+ smod = FPAddSpecialCasesMod(self.width, self.pspec)
+ dmod = FPAddDeNormMod(self.width, self.pspec, True)
chain = StageChain([smod, dmod])
chain.setup(m, i)
class FPCorrectionsMod(Elaboratable):
- def __init__(self, width, id_wid, op_wid=None):
+ def __init__(self, width, pspec):
self.width = width
- self.id_wid = id_wid
- self.op_wid = op_wid # operand width
+ self.pspec = pspec
self.i = self.ispec()
self.out_z = self.ospec()
def ispec(self):
- return FPRoundData(self.width, self.id_wid, self.op_wid)
+ return FPRoundData(self.width, self.pspec)
def ospec(self):
- return FPRoundData(self.width, self.id_wid, self.op_wid)
+ return FPRoundData(self.width, self.pspec)
def process(self, i):
return self.out_z
self.mod.setup(m, in_z)
m.d.sync += self.out_z.eq(self.mod.out_z)
- m.d.sync += self.out_z.mid.eq(self.mod.o.mid)
+ m.d.sync += self.out_z.ctx.eq(self.mod.o.ctx)
def action(self, m):
m.next = "pack"
from ieee754.fpcommon.fpbase import FPNumIn, FPNumOut, FPNumBaseRecord
from ieee754.fpcommon.fpbase import FPState, FPNumBase
+from ieee754.fpcommon.getop import FPBaseData
class FPSCData:
- def __init__(self, width, id_wid, m_extra=True, op_wid=None):
+ def __init__(self, width, pspec, m_extra):
# NOTE: difference between z and oz is that oz is created by
# special-cases module(s) and will propagate, along with its
self.z = FPNumBaseRecord(width, False) # denormed result
self.oz = Signal(width, reset_less=True) # "finished" (bypass) result
self.out_do_z = Signal(reset_less=True) # "bypass" enabled
- self.mid = Signal(id_wid, reset_less=True) # multiplexer ID
- self.op_wid = op_wid
- if op_wid:
- self.op = Signal(op_wid, reset_less=True) # operand
-
+ self.ctx = FPBaseData(width, pspec)
+ self.mid = self.ctx.mid
def __iter__(self):
yield from self.a
yield from self.z
yield self.oz
yield self.out_do_z
- yield self.mid
- if op_wid:
- yield self.op
+ yield from self.ctx
def eq(self, i):
ret = [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
- self.a.eq(i.a), self.b.eq(i.b), self.mid.eq(i.mid)]
- if self.op_wid:
- ret.append(self.op.eq(i.op))
+ self.a.eq(i.a), self.b.eq(i.b), self.ctx.eq(i.ctx)]
return ret
class FPAddDeNormMod(FPState, Elaboratable):
- def __init__(self, width, id_wid, m_extra=True, op_wid=None):
+ def __init__(self, width, pspec, m_extra):
self.width = width
- self.id_wid = id_wid
+ self.pspec = pspec
self.m_extra = m_extra
- self.op_wid = op_wid
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPSCData(self.width, self.id_wid, self.m_extra, self.op_wid)
+ return FPSCData(self.width, self.pspec, self.m_extra)
def ospec(self):
- return FPSCData(self.width, self.id_wid, self.m_extra, self.op_wid)
+ return FPSCData(self.width, self.pspec, self.m_extra)
def process(self, i):
return self.o
with m.Else():
m.d.comb += self.o.b.m[-1].eq(1) # set top mantissa bit
- m.d.comb += self.o.mid.eq(self.i.mid)
+ m.d.comb += self.o.ctx.eq(self.i.ctx)
m.d.comb += self.o.z.eq(self.i.z)
m.d.comb += self.o.out_do_z.eq(self.i.out_do_z)
m.d.comb += self.o.oz.eq(self.i.oz)
class FPBaseData:
- def __init__(self, n_ops, width, id_wid, op_wid):
+ def __init__(self, width, pspec):
self.width = width
- self.id_wid = id_wid
- self.op_wid = op_wid
+ print (pspec)
+ self.id_wid = pspec['id_wid']
+ self.op_wid = pspec.get('op_wid', 0)
+ self.mid = Signal(self.id_wid, reset_less=True) # RS multiplex ID
+ self.op = Signal(self.op_wid, reset_less=True)
+
+ def eq(self, i):
+ ret = [self.mid.eq(i.mid)]
+ if self.op_wid:
+ ret.append(self.op.eq(i.op))
+ return ret
+
+ def __iter__(self):
+ yield self.mid
+ if self.op_wid:
+ yield self.op
+
+ def ports(self):
+ return list(self)
+
+
+class FPADDBaseData:
+
+ def __init__(self, width, pspec, n_ops=2):
+ self.width = width
+ self.ctx = FPBaseData(width, pspec)
ops = []
for i in range(n_ops):
name = chr(ord("a")+i)
operand = Signal(width, name=name)
setattr(self, name, operand)
ops.append(operand)
+ self.mid = self.ctx.mid # make muxid available here: complicated
self.ops = ops
- self.mid = Signal(id_wid, reset_less=True) # RS multiplex ID
- self.op = Signal(op_wid, reset_less=True)
def eq(self, i):
ret = []
for op1, op2 in zip(self.ops, i.ops):
ret.append(op1.eq(op2))
- ret.append(self.mid.eq(i.mid))
- if self.op_wid:
- ret.append(self.op.eq(i.op))
+ ret.append(self.ctx.eq(i.ctx))
return ret
def __iter__(self):
if self.ops:
yield from self.ops
- yield self.mid
- if self.id_wid:
- yield self.op
+ yield from self.ctx
def ports(self):
return list(self)
-class FPADDBaseData(FPBaseData):
-
- def __init__(self, width, id_wid, op_wid):
- FPBaseData.__init__(self, 2, width, id_wid, op_wid)
-
class FPGet2OpMod(PrevControl):
def __init__(self, width, id_wid, op_wid=None):
class FPNormToPack(FPState, SimpleHandshake):
- def __init__(self, width, id_wid, op_wid=None):
+ def __init__(self, width, pspec):
FPState.__init__(self, "normalise_1")
- self.id_wid = id_wid
- self.op_wid = op_wid
+ self.pspec = pspec
self.width = width
SimpleHandshake.__init__(self, self) # pipeline is its own stage
def ispec(self):
- return FPAddStage1Data(self.width, self.id_wid, self.op_wid)
+ return FPAddStage1Data(self.width, self.pspec)
def ospec(self):
- return FPPackData(self.width, self.id_wid, self.op_wid) # FPPackMod
+ return FPPackData(self.width, self.pspec) # FPPackMod
def setup(self, m, i):
""" links module to inputs and outputs
"""
# Normalisation, Rounding Corrections, Pack - in a chain
- nmod = FPNorm1ModSingle(self.width, self.id_wid)
- rmod = FPRoundMod(self.width, self.id_wid)
- cmod = FPCorrectionsMod(self.width, self.id_wid)
- pmod = FPPackMod(self.width, self.id_wid)
+ nmod = FPNorm1ModSingle(self.width, self.pspec)
+ rmod = FPRoundMod(self.width, self.pspec)
+ cmod = FPCorrectionsMod(self.width, self.pspec)
+ pmod = FPPackMod(self.width, self.pspec)
stages = [nmod, rmod, cmod, pmod]
chain = StageChain(stages)
chain.setup(m, i)
class FPPackData(Object):
- def __init__(self, width, id_wid, op_wid):
+ def __init__(self, width, pspec):
Object.__init__(self)
self.z = Signal(width, reset_less=True) # result
- self.mid = Signal(id_wid, reset_less=True) # multiplex ID
- self.op = Signal(op_wid or 0, reset_less=True) # operand width
-
+ self.ctx = FPBaseData(width, pspec)
+ self.mid = self.ctx.mid
class FPPackMod(Elaboratable):
- def __init__(self, width, id_wid, op_wid=None):
+ def __init__(self, width, pspec):
self.width = width
- self.id_wid = id_wid
- self.op_wid = op_wid
+ self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPRoundData(self.width, self.id_wid, self.op_wid)
+ return FPRoundData(self.width, self.pspec)
def ospec(self):
- return FPPackData(self.width, self.id_wid, self.op_wid)
+ return FPPackData(self.width, self.pspec)
def process(self, i):
return self.o
z = FPNumBaseRecord(self.width, False)
m.submodules.pack_in_z = in_z = FPNumBase(self.i.z)
#m.submodules.pack_out_z = out_z = FPNumOut(z)
- m.d.comb += self.o.mid.eq(self.i.mid)
- if self.i.op_wid:
- m.d.comb += self.o.op.eq(self.i.op)
+ m.d.comb += self.o.ctx.eq(self.i.ctx)
with m.If(~self.i.out_do_z):
with m.If(in_z.is_overflowed):
m.d.comb += z.inf(self.i.z.s)
self.mod.setup(m, in_z)
m.d.sync += self.out_z.v.eq(self.mod.out_z.v)
- m.d.sync += self.out_z.mid.eq(self.mod.o.mid)
+ m.d.sync += self.out_z.ctx.eq(self.mod.o.ctx)
def action(self, m):
m.next = "pack_put_z"
from ieee754.fpcommon.fpbase import Overflow, FPNumBaseRecord
from ieee754.fpcommon.getop import FPBaseData
-class FPAddStage1Data(FPBaseData):
+class FPAddStage1Data:
- def __init__(self, width, id_wid, op_wid=None):
- FPBaseData.__init__(self, 0, width, id_wid, op_wid)
+ def __init__(self, width, pspec):
self.z = FPNumBaseRecord(width, False)
self.out_do_z = Signal(reset_less=True)
self.oz = Signal(width, reset_less=True)
self.of = Overflow()
+ self.ctx = FPBaseData(width, pspec)
+ self.mid = self.ctx.mid
def __iter__(self):
yield from self.z
yield self.out_do_z
yield self.oz
yield from self.of
- yield from FPBaseData.__iter__(self)
+ yield from self.ctx
def eq(self, i):
- ret = [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
- self.of.eq(i.of),] + FPBaseData.eq(self, i)
-
- return ret
+ return [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
+ self.of.eq(i.of), self.ctx.eq(i.ctx)]
from ieee754.fpcommon.fpbase import Overflow, FPNumBase, FPNumBaseRecord
from ieee754.fpcommon.fpbase import MultiShiftRMerge
from ieee754.fpcommon.fpbase import FPState
+from ieee754.fpcommon.getop import FPBaseData
from .postcalc import FPAddStage1Data
class FPNorm1Data:
- def __init__(self, width, id_wid, op_wid=None):
+ def __init__(self, width, pspec):
self.roundz = Signal(reset_less=True, name="norm1_roundz")
self.z = FPNumBaseRecord(width, False)
self.out_do_z = Signal(reset_less=True)
self.oz = Signal(width, reset_less=True)
- self.mid = Signal(id_wid, reset_less=True)
- self.op_wid = op_wid
- if op_wid:
- self.op = Signal(op_wid, reset_less=True) # operand
+ self.ctx = FPBaseData(width, pspec)
+ self.mid = self.ctx.mid
def eq(self, i):
ret = [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
- self.roundz.eq(i.roundz), self.mid.eq(i.mid)]
- if self.op_wid:
- ret.append(self.op.eq(i.op))
+ self.roundz.eq(i.roundz), self.ctx.eq(i.ctx)]
return ret
class FPNorm1ModSingle(Elaboratable):
- def __init__(self, width, id_wid, op_wid=None):
+ def __init__(self, width, pspec):
self.width = width
- self.id_wid = id_wid
- self.op_wid = op_wid
+ self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPAddStage1Data(self.width, self.id_wid, self.op_wid)
+ return FPAddStage1Data(self.width, self.pspec)
def ospec(self):
- return FPNorm1Data(self.width, self.id_wid, self.op_wid)
+ return FPNorm1Data(self.width, self.pspec)
def setup(self, m, i):
""" links module to inputs and outputs
self.o.z.e.eq(insel_z.e + ediff_n126),
]
- m.d.comb += self.o.mid.eq(self.i.mid)
+ m.d.comb += self.o.ctx.eq(self.i.ctx)
m.d.comb += self.o.out_do_z.eq(self.i.out_do_z)
m.d.comb += self.o.oz.eq(self.i.oz)
from ieee754.fpcommon.fpbase import FPNumBase, FPNumBaseRecord
from ieee754.fpcommon.fpbase import FPState
+from ieee754.fpcommon.getop import FPBaseData
from .postnormalise import FPNorm1Data
class FPRoundData:
- def __init__(self, width, id_wid, op_wid=None):
+ def __init__(self, width, pspec):
self.z = FPNumBaseRecord(width, False)
- self.mid = Signal(id_wid, reset_less=True) # multiplex ID
+ self.ctx = FPBaseData(width, pspec)
+ self.mid = self.ctx.mid
# pipeline bypass [data comes from specialcases]
self.out_do_z = Signal(reset_less=True)
self.oz = Signal(width, reset_less=True)
- self.op_wid = op_wid
- if op_wid:
- self.op = Signal(op_wid, reset_less=True)
def eq(self, i):
ret = [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
- self.mid.eq(i.mid)]
- if self.op_wid:
- ret.append(self.op.eq(i.op))
+ self.ctx.eq(i.ctx)]
return ret
-
class FPRoundMod(Elaboratable):
- def __init__(self, width, id_wid, op_wid=None):
+ def __init__(self, width, pspec):
self.width = width
- self.id_wid = id_wid
- self.op_wid = op_wid
+ self.pspec = pspec
self.i = self.ispec()
self.out_z = self.ospec()
def ispec(self):
- return FPNorm1Data(self.width, self.id_wid, self.op_wid)
+ return FPNorm1Data(self.width, self.pspec)
def ospec(self):
- return FPRoundData(self.width, self.id_wid, self.op_wid)
+ return FPRoundData(self.width, self.pspec)
def process(self, i):
return self.out_z
self.idsync(m)
m.d.sync += self.out_z.eq(self.mod.out_z)
- m.d.sync += self.out_z.mid.eq(self.mod.o.mid)
+ m.d.sync += self.out_z.ctx.eq(self.mod.o.ctx)
def action(self, m):
m.next = "corrections"
class FPMulStage0Data:
- def __init__(self, width, id_wid, op_wid=None):
- FPBaseData.__init__(self, 0, width, id_wid, op_wid)
+ def __init__(self, width, pspec):
self.z = FPNumBaseRecord(width, False)
self.out_do_z = Signal(reset_less=True)
self.oz = Signal(width, reset_less=True)
mw = (self.z.m_width)*2 - 1 + 3 # sticky/round/guard bits + (2*mant) - 1
self.product = Signal(mw, reset_less=True)
+ self.ctx = FPBaseData(width, pspec)
+ self.mid = self.ctx.mid
def eq(self, i):
return [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
- self.product.eq(i.product)] + FPBaseData.eq(self, i)
+ self.product.eq(i.product), self.ctx.eq(i.ctx)]
class FPMulStage0Mod(Elaboratable):
- def __init__(self, width, id_wid, op_wid=None):
+ def __init__(self, width, pspec):
self.width = width
- self.id_wid = id_wid
- self.op_wid = op_wid
+ self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPSCData(self.width, self.id_wid, False, self.op_wid)
+ return FPSCData(self.width, self.pspec, False)
def ospec(self):
- return FPMulStage0Data(self.width, self.id_wid, self.op_wid)
+ return FPMulStage0Data(self.width, self.pspec)
def process(self, i):
return self.o
m.d.comb += self.o.oz.eq(self.i.oz)
m.d.comb += self.o.out_do_z.eq(self.i.out_do_z)
- m.d.comb += self.o.mid.eq(self.i.mid)
- if self.o.op_wid:
- m.d.comb += self.o.op.eq(self.i.op)
+ m.d.comb += self.o.ctx.eq(self.i.ctx)
return m
""" Second stage of mul: preparation for normalisation.
"""
- def __init__(self, width, id_wid, op_wid=None):
+ def __init__(self, width, pspec):
self.width = width
- self.id_wid = id_wid
- self.op_wid = op_wid
+ self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPMulStage0Data(self.width, self.id_wid, self.op_wid)
+ return FPMulStage0Data(self.width, self.pspec)
def ospec(self):
- return FPAddStage1Data(self.width, self.id_wid, self.op_wid)
+ return FPAddStage1Data(self.width, self.pspec)
def process(self, i):
return self.o
m.d.comb += self.o.out_do_z.eq(self.i.out_do_z)
m.d.comb += self.o.oz.eq(self.i.oz)
- m.d.comb += self.o.mid.eq(self.i.mid)
- if self.o.op_wid:
- m.d.comb += self.o.op.eq(self.i.op)
+ m.d.comb += self.o.ctx.eq(self.i.ctx)
return m
class FPMulStage1(FPState):
- def __init__(self, width, id_wid):
+ def __init__(self, width, pspec):
FPState.__init__(self, "multiply_1")
- self.mod = FPMulStage1Mod(width)
+ self.mod = FPMulStage1Mod(width, pspec)
self.out_z = FPNumBaseRecord(width, False)
self.out_of = Overflow()
self.norm_stb = Signal()
class FPMulStages(FPState, SimpleHandshake):
- def __init__(self, width, id_wid, op_wid=None):
+ def __init__(self, width, pspec):
FPState.__init__(self, "align")
self.width = width
- self.id_wid = id_wid
- self.op_wid = op_wid
+ self.pspec = pspec
SimpleHandshake.__init__(self, self) # pipeline is its own stage
self.m1o = self.ospec()
def ispec(self):
- return FPSCData(self.width, self.id_wid, False, self.op_wid)
+ return FPSCData(self.width, self.pspec, False)
def ospec(self):
- return FPAddStage1Data(self.width, self.id_wid, self.op_wid)
+ return FPAddStage1Data(self.width, self.pspec)
def setup(self, m, i):
""" links module to inputs and outputs
"""
# chain MulStage0 and MulStage1
- m0mod = FPMulStage0Mod(self.width, self.id_wid, self.op_wid)
- m1mod = FPMulStage1Mod(self.width, self.id_wid, self.op_wid)
+ m0mod = FPMulStage0Mod(self.width, self.pspec)
+ m1mod = FPMulStage1Mod(self.width, self.pspec)
chain = StageChain([m0mod, m1mod])
chain.setup(m, i)
class FPMULBasePipe(ControlBase):
- def __init__(self, width, id_wid):
+ def __init__(self, width, pspec):
ControlBase.__init__(self)
- self.pipe1 = FPMulSpecialCasesDeNorm(width, id_wid)
- self.pipe2 = FPMulStages(width, id_wid)
- self.pipe3 = FPNormToPack(width, id_wid)
+ self.pipe1 = FPMulSpecialCasesDeNorm(width, pspec)
+ self.pipe2 = FPMulStages(width, pspec)
+ self.pipe3 = FPNormToPack(width, pspec)
self._eqs = self.connect([self.pipe1, self.pipe2, self.pipe3])
"""
def __init__(self, width, num_rows, op_wid=0):
self.width = width
+ self.pspec = {}
self.id_wid = num_bits(width)
self.op_wid = op_wid
- self.alu = FPMULBasePipe(width, self.id_wid)
+ self.pspec['id_wid'] = self.id_wid
+ self.pspec['op_wid'] = self.op_wid
+ self.alu = FPMULBasePipe(width, self.pspec)
ReservationStations.__init__(self, num_rows)
def i_specfn(self):
- return FPADDBaseData(self.width, self.id_wid, self.op_wid)
+ return FPADDBaseData(self.width, self.pspec)
def o_specfn(self):
- return FPPackData(self.width, self.id_wid, self.op_wid)
+ return FPPackData(self.width, self.pspec)
https://steve.hollasch.net/cgindex/coding/ieeefloat.html
"""
- def __init__(self, width, id_wid, op_wid=None):
+ def __init__(self, width, pspec):
self.width = width
- self.id_wid = id_wid
- self.op_wid = op_wid
+ self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPADDBaseData(self.width, self.id_wid, self.op_wid)
+ return FPADDBaseData(self.width, self.pspec)
def ospec(self):
- return FPSCData(self.width, self.id_wid, False, self.op_wid)
+ return FPSCData(self.width, self.pspec, False)
def setup(self, m, i):
""" links module to inputs and outputs
m.d.comb += self.o.out_do_z.eq(0)
m.d.comb += self.o.oz.eq(self.o.z.v)
- m.d.comb += self.o.mid.eq(self.i.mid)
+ m.d.comb += self.o.ctx.eq(self.i.ctx)
return m
"""
self.mod.setup(m, i, self.out_do_z)
m.d.sync += self.out_z.v.eq(self.mod.out_z.v) # only take the output
- m.d.sync += self.out_z.mid.eq(self.mod.o.mid) # (and mid)
+ m.d.sync += self.out_z.ctx.eq(self.mod.o.ctx) # (and context)
def action(self, m):
self.idsync(m)
""" special cases: NaNs, infs, zeros, denormalised
"""
- def __init__(self, width, id_wid, op_wid=None):
+ def __init__(self, width, pspec):
FPState.__init__(self, "special_cases")
self.width = width
- self.id_wid = id_wid
- self.op_wid = op_wid
+ self.pspec = pspec
SimpleHandshake.__init__(self, self) # pipe is its own stage
self.out = self.ospec()
def ispec(self):
- return FPADDBaseData(self.width, self.id_wid, self.op_wid)
+ return FPADDBaseData(self.width, self.pspec)
def ospec(self):
- return FPSCData(self.width, self.id_wid, False, self.op_wid)
+ return FPSCData(self.width, self.pspec, False)
def setup(self, m, i):
""" links module to inputs and outputs
"""
- smod = FPMulSpecialCasesMod(self.width, self.id_wid)
- dmod = FPAddDeNormMod(self.width, self.id_wid, False)
+ smod = FPMulSpecialCasesMod(self.width, self.pspec)
+ dmod = FPAddDeNormMod(self.width, self.pspec, False)
chain = StageChain([smod, dmod])
chain.setup(m, i)
# multiplexer id taken from n_mux
mid = self.n_mux.m_id
+ print ("self.n_mux", self.n_mux)
+ print ("self.n_mux.m_id", self.n_mux.m_id)
# temporaries
p_valid_i = Signal(reset_less=True)
CombMultiOutPipeline.__init__(self, stage, n_len=n_len, n_mux=stage)
# HACK: n-mux is also the stage... so set the muxid equal to input mid
+ print ("combmuxout", self.p.data_i.mid)
stage.m_id = self.p.data_i.mid
def arrayproxy_iter2(self, ao, ai):
for p in ai.ports():
+ print ("arrayproxy - p", p, p.name, ao)
op = getattr(ao, p.name)
- print ("arrayproxy - p", p, p.name)
yield from self.iterator2(op, p)