""" input data base type for ``DivPipe``.
"""
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
""" Create a ``DivPipeBaseData`` instance. """
+ width = pspec['width']
self.out_do_z = Signal(reset_less=True)
self.oz = Signal(width, reset_less=True)
- self.ctx = FPPipeContext(width, pspec) # context: muxid, operator etc.
+ self.ctx = FPPipeContext(pspec) # context: muxid, operator etc.
self.muxid = self.ctx.muxid # annoying. complicated.
def __iter__(self):
def __init__(self, core_config):
""" Create a ``DivPipeInputData`` instance. """
DivPipeCoreInputData.__init__(self, core_config)
- DivPipeBaseData.__init__(self, width, pspec) # XXX TODO args
+ DivPipeBaseData.__init__(self, pspec) # XXX TODO args
self.out_do_z = Signal(reset_less=True)
self.oz = Signal(width, reset_less=True)
- self.ctx = FPPipeContext(width, pspec) # context: muxid, operator etc.
+ self.ctx = FPPipeContext(pspec) # context: muxid, operator etc.
self.muxid = self.ctx.muxid # annoying. complicated.
def __iter__(self):
def __init__(self, core_config):
""" Create a ``DivPipeCoreInterstageData`` instance. """
DivPipeCoreInterstageData.__init__(self, core_config)
- DivPipeBaseData.__init__(self, width, pspec) # XXX TODO args
+ DivPipeBaseData.__init__(self, pspec) # XXX TODO args
def __iter__(self):
""" Get member signals. """
def __init__(self, core_config):
""" Create a ``DivPipeCoreOutputData`` instance. """
DivPipeCoreOutputData.__init__(self, core_config)
- DivPipeBaseData.__init__(self, width, pspec) # XXX TODO args
+ DivPipeBaseData.__init__(self, pspec) # XXX TODO args
def __iter__(self):
""" Get member signals. """
https://steve.hollasch.net/cgindex/coding/ieeefloat.html
"""
- def __init__(self, in_width, out_width, in_pspec, out_pspec):
- self.in_width = in_width
- self.out_width = out_width
+ def __init__(self, in_pspec, out_pspec):
self.in_pspec = in_pspec
self.out_pspec = out_pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPADDBaseData(self.in_width, self.in_pspec)
+ return FPADDBaseData(self.in_pspec)
def ospec(self):
- return FPAddStage1Data(self.out_width, self.out_pspec)
+ return FPAddStage1Data(self.out_pspec)
def setup(self, m, i):
""" links module to inputs and outputs
#m.submodules.sc_out_z = self.o.z
# decode: XXX really should move to separate stage
- print ("in_width out", self.in_width, self.out_width)
- a1 = FPNumBaseRecord(self.in_width, False)
+ print ("in_width out", self.in_pspec['width'],
+ self.out_pspec['width'])
+ a1 = FPNumBaseRecord(self.in_pspec['width'], False)
m.submodules.sc_decode_a = a1 = FPNumDecode(None, a1)
m.d.comb += a1.v.eq(self.i.a)
z1 = self.o.z
""" special cases: NaNs, infs, zeros, denormalised
"""
- def __init__(self, in_width, out_width, in_pspec, out_pspec):
+ def __init__(self, in_pspec, out_pspec):
FPState.__init__(self, "special_cases")
- sc = FPCVTSpecialCasesMod(in_width, out_width, in_pspec, out_pspec)
+ sc = FPCVTSpecialCasesMod(in_pspec, out_pspec)
SimpleHandshake.__init__(self, sc)
self.out = self.ospec(None)
class FPCVTBasePipe(ControlBase):
- def __init__(self, in_width, out_width, in_pspec, out_pspec):
+ def __init__(self, in_pspec, out_pspec):
ControlBase.__init__(self)
- self.pipe1 = FPCVTSpecialCasesDeNorm(in_width, out_width,
- in_pspec, out_pspec)
- self.pipe2 = FPNormToPack(out_width, out_pspec)
+ self.pipe1 = FPCVTSpecialCasesDeNorm(in_pspec, out_pspec)
+ self.pipe2 = FPNormToPack(out_pspec)
self._eqs = self.connect([self.pipe1, self.pipe2])
Fan-in and Fan-out are combinatorial.
"""
def __init__(self, in_width, out_width, num_rows, op_wid=0):
- self.in_width = in_width
- self.out_width = out_width
self.op_wid = op_wid
self.id_wid = num_bits(in_width)
self.out_id_wid = num_bits(out_width)
self.in_pspec = {}
self.in_pspec['id_wid'] = self.id_wid
self.in_pspec['op_wid'] = self.op_wid
+ self.in_pspec['width'] = self.in_width
self.out_pspec = {}
self.out_pspec['id_wid'] = self.out_id_wid
- self.out_pspec['op_wid'] = self.op_wid
+ self.out_pspec['op_wid'] = op_wid
+ self.out_pspec['width'] = out_width
- self.alu = FPCVTBasePipe(in_width, out_width,
- self.in_pspec, self.out_pspec)
+ self.alu = FPCVTBasePipe(self.in_pspec, self.out_pspec)
ReservationStations.__init__(self, num_rows)
def i_specfn(self):
- return FPADDBaseData(self.in_width, self.in_pspec)
+ return FPADDBaseData(self.in_pspec)
def o_specfn(self):
- return FPPackData(self.out_width, self.out_pspec)
+ return FPPackData(self.out_pspec)
class FPAddStage0Data:
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
+ width = pspec['width']
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.ctx = FPPipeContext(width, pspec)
+ self.ctx = FPPipeContext(pspec)
self.muxid = self.ctx.muxid
def eq(self, i):
class FPAddStage0Mod(Elaboratable):
- def __init__(self, width, pspec):
- self.width = width
+ def __init__(self, pspec):
self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPSCData(self.width, self.pspec, True)
+ return FPSCData(self.pspec, True)
def ospec(self):
- return FPAddStage0Data(self.width, self.pspec)
+ return FPAddStage0Data(self.pspec)
def process(self, i):
return self.o
give greatest accuracy.
"""
- def __init__(self, width, pspec):
+ def __init__(self, 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, pspec):
- self.width = width
+ def __init__(self, pspec):
self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPAddStage0Data(self.width, self.pspec)
+ return FPAddStage0Data(self.pspec)
def ospec(self):
- return FPAddStage1Data(self.width, self.pspec)
+ return FPAddStage1Data(self.pspec)
def process(self, i):
return self.o
class FPAddStage1(FPState):
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
FPState.__init__(self, "add_1")
self.mod = FPAddStage1Mod(width)
self.out_z = FPNumBase(width, False)
class FPAddAlignSingleAdd(FPState, SimpleHandshake):
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
FPState.__init__(self, "align")
- self.width = width
self.pspec = pspec
SimpleHandshake.__init__(self, self) # pipeline is its own stage
self.a1o = self.ospec()
def ispec(self):
- return FPSCData(self.width, self.pspec, True)
+ return FPSCData(self.pspec, True)
def ospec(self):
- return FPAddStage1Data(self.width, self.pspec) # AddStage1 ospec
+ return FPAddStage1Data(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.pspec)
- a0mod = FPAddStage0Mod(self.width, self.pspec)
- a1mod = FPAddStage1Mod(self.width, self.pspec)
+ mod = FPAddAlignSingleMod(self.pspec)
+ a0mod = FPAddStage0Mod(self.pspec)
+ a1mod = FPAddStage1Mod(self.pspec)
chain = StageChain([mod, a0mod, a1mod])
chain.setup(m, i)
class FPNumIn2Ops:
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
+ width = pspec['width']
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.ctx = FPPipeContext(width, pspec)
+ self.ctx = FPPipeContext(pspec)
self.muxid = self.ctx.muxid
def eq(self, i):
class FPAddAlignMulti(FPState):
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
FPState.__init__(self, "align")
- self.mod = FPAddAlignMultiMod(width, pspec)
+ self.mod = FPAddAlignMultiMod(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, pspec):
- self.width = width
+ def __init__(self, pspec):
self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPSCData(self.width, self.pspec, True)
+ return FPSCData(self.pspec, True)
def ospec(self):
- return FPNumIn2Ops(self.width, self.pspec)
+ return FPNumIn2Ops(self.pspec)
def process(self, i):
return self.o
#m.submodules.align_out_b = self.o.b
# temporary (muxed) input and output to be shifted
- t_inp = FPNumBaseRecord(self.width)
- t_out = FPNumBaseRecord(self.width)
+ width = self.pspec['width']
+ t_inp = FPNumBaseRecord(width)
+ t_out = FPNumBaseRecord(width)
espec = (len(self.i.a.e), True)
msr = MultiShiftRMerge(self.i.a.m_width, espec)
#m.submodules.align_t_in = t_inp
class FPAddAlignSingle(FPState):
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
FPState.__init__(self, "align")
- self.mod = FPAddAlignSingleMod(width, pspec)
+ width = pspec['width']
+ self.mod = FPAddAlignSingleMod(pspec)
self.out_a = FPNumIn(None, width)
self.out_b = FPNumIn(None, width)
class FPADDBasePipe(ControlBase):
- def __init__(self, width, id_wid):
+ def __init__(self, pspec):
ControlBase.__init__(self)
- self.pipe1 = FPAddSpecialCasesDeNorm(width, id_wid)
- self.pipe2 = FPAddAlignSingleAdd(width, id_wid)
- self.pipe3 = FPNormToPack(width, id_wid)
+ self.pipe1 = FPAddSpecialCasesDeNorm(pspec)
+ self.pipe2 = FPAddAlignSingleAdd(pspec)
+ self.pipe3 = FPNormToPack(pspec)
self._eqs = self.connect([self.pipe1, self.pipe2, self.pipe3])
Fan-in and Fan-out are combinatorial.
"""
def __init__(self, width, num_rows, op_wid=None):
- self.width = width
self.id_wid = num_bits(width)
self.op_wid = op_wid
- self.pspec = {'id_wid': self.id_wid, 'op_wid': op_wid}
- self.alu = FPADDBasePipe(width, self.pspec)
+ self.pspec = {'width': width, 'id_wid': self.id_wid, 'op_wid': op_wid}
+ self.alu = FPADDBasePipe(self.pspec)
ReservationStations.__init__(self, num_rows)
def i_specfn(self):
- return FPADDBaseData(self.width, self.pspec)
+ return FPADDBaseData(self.pspec)
def o_specfn(self):
- return FPPackData(self.width, self.pspec)
+ return FPPackData(self.pspec)
https://steve.hollasch.net/cgindex/coding/ieeefloat.html
"""
- def __init__(self, width, pspec):
- self.width = width
+ def __init__(self, pspec):
self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPADDBaseData(self.width, self.pspec)
+ return FPADDBaseData(self.pspec)
def ospec(self):
- return FPSCData(self.width, self.pspec, True)
+ return FPSCData(self.pspec, True)
def setup(self, m, i):
""" links module to inputs and outputs
#m.submodules.sc_out_z = self.o.z
# decode: XXX really should move to separate stage
- a1 = FPNumBaseRecord(self.width)
- b1 = FPNumBaseRecord(self.width)
+ width = self.pspec['width']
+ a1 = FPNumBaseRecord(width)
+ b1 = FPNumBaseRecord(width)
m.submodules.sc_decode_a = a1 = FPNumDecode(None, a1)
m.submodules.sc_decode_b = b1 = FPNumDecode(None, b1)
m.d.comb += [a1.v.eq(self.i.a),
https://steve.hollasch.net/cgindex/coding/ieeefloat.html
"""
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
FPState.__init__(self, "special_cases")
- self.width = width
self.pspec = pspec
SimpleHandshake.__init__(self, self) # pipe is its own stage
self.out = self.ospec()
def ispec(self):
- return FPADDBaseData(self.width, self.pspec) # SC ispec
+ return FPADDBaseData(self.pspec) # SC ispec
def ospec(self):
- return FPSCData(self.width, self.pspec, True) # DeNorm
+ return FPSCData(self.pspec, True) # DeNorm
def setup(self, m, i):
""" links module to inputs and outputs
"""
- smod = FPAddSpecialCasesMod(self.width, self.pspec)
- dmod = FPAddDeNormMod(self.width, self.pspec, True)
+ smod = FPAddSpecialCasesMod(self.pspec)
+ dmod = FPAddDeNormMod(self.pspec, True)
chain = StageChain([smod, dmod])
chain.setup(m, i)
class FPCorrectionsMod(Elaboratable):
- def __init__(self, width, pspec):
- self.width = width
+ def __init__(self, pspec):
self.pspec = pspec
self.i = self.ispec()
self.out_z = self.ospec()
def ispec(self):
- return FPRoundData(self.width, self.pspec)
+ return FPRoundData(self.pspec)
def ospec(self):
- return FPRoundData(self.width, self.pspec)
+ return FPRoundData(self.pspec)
def process(self, i):
return self.out_z
class FPSCData:
- def __init__(self, width, pspec, m_extra):
-
+ def __init__(self, pspec, m_extra):
+ width = pspec['width']
# NOTE: difference between z and oz is that oz is created by
# special-cases module(s) and will propagate, along with its
# "bypass" signal out_do_z, through the pipeline, *disabling*
# all processing of all subsequent stages.
self.a = FPNumBaseRecord(width, m_extra) # operand a
self.b = FPNumBaseRecord(width, m_extra) # operand b
- self.z = FPNumBaseRecord(width, False) # denormed result
+ 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.ctx = FPPipeContext(width, pspec)
+ self.ctx = FPPipeContext(pspec)
self.muxid = self.ctx.muxid
def __iter__(self):
class FPAddDeNormMod(FPState, Elaboratable):
- def __init__(self, width, pspec, m_extra):
- self.width = width
+ def __init__(self, pspec, m_extra):
self.pspec = pspec
self.m_extra = m_extra
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPSCData(self.width, self.pspec, self.m_extra)
+ return FPSCData(self.pspec, self.m_extra)
def ospec(self):
- return FPSCData(self.width, self.pspec, self.m_extra)
+ return FPSCData(self.pspec, self.m_extra)
def process(self, i):
return self.o
class FPPipeContext:
- def __init__(self, width, pspec):
- self.width = width
+ def __init__(self, pspec):
print (pspec)
self.id_wid = pspec['id_wid']
self.op_wid = pspec.get('op_wid', 0)
class FPADDBaseData:
- def __init__(self, width, pspec, n_ops=2):
- self.width = width
- self.ctx = FPPipeContext(width, pspec)
+ def __init__(self, pspec, n_ops=2):
+ width = pspec['width']
+ self.ctx = FPPipeContext(pspec)
ops = []
for i in range(n_ops):
name = chr(ord("a")+i)
class FPNormToPack(FPState, SimpleHandshake):
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
FPState.__init__(self, "normalise_1")
print ("normtopack", pspec)
self.pspec = pspec
- self.width = width
SimpleHandshake.__init__(self, self) # pipeline is its own stage
def ispec(self):
- return FPAddStage1Data(self.width, self.pspec)
+ return FPAddStage1Data(self.pspec)
def ospec(self):
- return FPPackData(self.width, self.pspec) # FPPackMod
+ return FPPackData(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.pspec)
- rmod = FPRoundMod(self.width, self.pspec)
- cmod = FPCorrectionsMod(self.width, self.pspec)
- pmod = FPPackMod(self.width, self.pspec)
+ nmod = FPNorm1ModSingle(self.pspec)
+ rmod = FPRoundMod(self.pspec)
+ cmod = FPCorrectionsMod(self.pspec)
+ pmod = FPPackMod(self.pspec)
stages = [nmod, rmod, cmod, pmod]
chain = StageChain(stages)
chain.setup(m, i)
class FPPackData:
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
+ width = pspec['width']
self.z = Signal(width, reset_less=True) # result
- self.ctx = FPPipeContext(width, pspec)
+ self.ctx = FPPipeContext(pspec)
# this is complicated: it's a workaround, due to the
# array-indexing not working properly in nmigen.
class FPPackMod(Elaboratable):
- def __init__(self, width, pspec):
- self.width = width
+ def __init__(self, pspec):
self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPRoundData(self.width, self.pspec)
+ return FPRoundData(self.pspec)
def ospec(self):
- return FPPackData(self.width, self.pspec)
+ return FPPackData(self.pspec)
def process(self, i):
return self.o
def elaborate(self, platform):
m = Module()
- z = FPNumBaseRecord(self.width, False)
+ z = FPNumBaseRecord(self.pspec['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.ctx.eq(self.i.ctx)
class FPAddStage1Data:
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
+ width = pspec['width']
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 = FPPipeContext(width, pspec)
+ self.ctx = FPPipeContext(pspec)
self.muxid = self.ctx.muxid
def __iter__(self):
class FPNorm1Data:
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
+ width = pspec['width']
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.ctx = FPPipeContext(width, pspec)
+ self.ctx = FPPipeContext(pspec)
self.muxid = self.ctx.muxid
def eq(self, i):
class FPNorm1ModSingle(Elaboratable):
- def __init__(self, width, pspec):
- self.width = width
+ def __init__(self, pspec):
self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPAddStage1Data(self.width, self.pspec)
+ return FPAddStage1Data(self.pspec)
def ospec(self):
- return FPNorm1Data(self.width, self.pspec)
+ return FPNorm1Data(self.pspec)
def setup(self, m, i):
""" links module to inputs and outputs
class FPNorm1ModMulti:
- def __init__(self, width, single_cycle=True):
+ def __init__(self, pspec, single_cycle=True):
self.width = width
self.in_select = Signal(reset_less=True)
self.in_z = FPNumBase(width, False)
class FPRoundData:
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
+ width = pspec['width']
self.z = FPNumBaseRecord(width, False)
- self.ctx = FPPipeContext(width, pspec)
+ self.ctx = FPPipeContext(pspec)
self.muxid = self.ctx.muxid
# pipeline bypass [data comes from specialcases]
self.out_do_z = Signal(reset_less=True)
class FPRoundMod(Elaboratable):
- def __init__(self, width, pspec):
- self.width = width
+ def __init__(self, pspec):
self.pspec = pspec
self.i = self.ispec()
self.out_z = self.ospec()
def ispec(self):
- return FPNorm1Data(self.width, self.pspec)
+ return FPNorm1Data(self.pspec)
def ospec(self):
- return FPRoundData(self.width, self.pspec)
+ return FPRoundData(self.pspec)
def process(self, i):
return self.out_z
# TODO: delete (replace by DivPipeCoreInputData)
class FPDivStage0Data:
- def __init__(self, width, pspec):
- self.z = FPNumBaseRecord(width, False)
+ def __init__(self, pspec):
+ self.z = FPNumBaseRecord(pspec['width'], False)
self.out_do_z = Signal(reset_less=True)
- self.oz = Signal(width, reset_less=True)
+ self.oz = Signal(pspec['width'], reset_less=True)
- self.ctx = FPPipeContext(width, pspec) # context: muxid, operator etc.
+ self.ctx = FPPipeContext(pspec['width'], pspec) # context: muxid, operator etc.
self.muxid = self.ctx.muxid # annoying. complicated.
# TODO: here is where Q and R would be put, and passed
class FPDivStage0Mod(Elaboratable):
- def __init__(self, width, id_wid):
- self.width = width
- self.id_wid = id_wid
+ def __init__(self, pspec):
+ self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPSCData(self.width, self.id_wid, False)
+ return FPSCData(self.pspec, False)
def ospec(self):
# XXX TODO: replace with DivPipeCoreInputData, here
- return FPDivStage0Data(self.width, self.id_wid)
+ return FPDivStage0Data(self.pspec)
def process(self, i):
return self.o
""" First stage of div.
"""
- def __init__(self, width, id_wid):
+ def __init__(self, pspec):
FPState.__init__(self, "divider_0")
- self.mod = FPDivStage0Mod(width)
+ self.mod = FPDivStage0Mod(pspec)
self.o = self.mod.ospec()
def setup(self, m, i):
class FPDivStage1Mod(Elaboratable):
- def __init__(self, width, pspec):
- self.width = width
+ def __init__(self, pspec):
self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
# TODO: DivPipeCoreInterstageData, here
- return FPDivStage0Data(self.width, self.pspec) # Q/Rem (etc) in...
+ return FPDivStage0Data(self.pspec) # Q/Rem (etc) in...
def ospec(self):
# TODO: DivPipeCoreInterstageData, here
- return FPDivStage0Data(self.width, self.pspec) # ... Q/Rem (etc) out
+ return FPDivStage0Data(self.pspec) # ... Q/Rem (etc) out
def process(self, i):
return self.o
""" Second stage of div: preparation for normalisation.
"""
- def __init__(self, width, pspec):
- self.width = width
+ def __init__(self, pspec):
self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
# TODO: DivPipeCoreInterstageData
- return FPDivStage0Data(self.width, self.pspec) # Q/Rem in...
+ return FPDivStage0Data(self.pspec) # Q/Rem in...
def ospec(self):
# XXX REQUIRED. MUST NOT BE CHANGED. this is the format
# required for ongoing processing (normalisation, correction etc.)
- return FPAddStage1Data(self.width, self.pspec) # out to post-process
+ return FPAddStage1Data(self.pspec) # out to post-process
def process(self, i):
return self.o
class FPDivStage2(FPState):
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
FPState.__init__(self, "divider_1")
- self.mod = FPDivStage2Mod(width)
- self.out_z = FPNumBaseRecord(width, False)
+ self.mod = FPDivStage2Mod(pspec)
+ self.out_z = FPNumBaseRecord(pspec, False)
self.out_of = Overflow()
self.norm_stb = Signal()
class FPDivStagesSetup(FPState, SimpleHandshake):
- def __init__(self, width, pspec, n_stages):
+ def __init__(self, pspec, n_stages):
FPState.__init__(self, "divsetup")
- self.width = width
self.pspec = pspec
self.n_stages = n_stages # number of combinatorial stages
SimpleHandshake.__init__(self, self) # pipeline is its own stage
def ispec(self):
# REQUIRED. do NOT change.
- return FPSCData(self.width, self.pspec, False) # from denorm
+ return FPSCData(self.pspec, False) # from denorm
def ospec(self):
# XXX TODO: replace with "intermediary" (DivPipeInterstageData)
- return FPDivStage0Data(self.width, self.pspec) # DIV ospec (loop)
+ return FPDivStage0Data(self.pspec) # DIV ospec (loop)
def setup(self, m, i):
""" links module to inputs and outputs.
divstages = []
# Converts from FPSCData into DivPipeInputData
- divstages.append(FPDivStage0Mod(self.width, self.pspec))
+ divstages.append(FPDivStage0Mod(self.pspec))
# does 1 "convert" (actual processing) from DivPipeInputData
# into "intermediate" output (DivPipeInterstageData)
# will add.
for count in range(self.n_stages): # number of combinatorial stages
# XXX: this can actually be entirely dropped...
- divstages.append(FPDivStage1Mod(self.width, self.pspec))
+ divstages.append(FPDivStage1Mod(self.pspec))
# ... and replaced with this.
# vvvvvvv
class FPDivStagesIntermediary(FPState, SimpleHandshake):
- def __init__(self, width, pspec, n_stages):
+ def __init__(self, pspec, n_stages):
FPState.__init__(self, "divintermediate")
- self.width = width
self.pspec = pspec
self.n_stages = n_stages # number of combinatorial stages
- self.begin = begin # "begin" mode
- self.end = end # "end" mode
SimpleHandshake.__init__(self, self) # pipeline is its own stage
self.m1o = self.ospec()
def ispec(self):
# TODO - this is for FPDivStage1Mod
# XXX TODO: replace with "intermediary" (DivPipeInterstageData)
- return FPDivStage0Data(self.width, self.pspec) # DIV ispec (loop)
+ return FPDivStage0Data(self.pspec) # DIV ispec (loop)
def ospec(self):
# TODO - this is for FPDivStage1Mod
# XXX TODO: replace with "intermediary" (DivPipeInterstageData)
- return FPDivStage0Data(self.width, self.pspec) # DIV ospec (loop)
+ return FPDivStage0Data(self.pspec) # DIV ospec (loop)
def setup(self, m, i):
""" links module to inputs and outputs.
# will add.
for count in range(self.n_stages): # number of combinatorial stages
# XXX: this can actually be entirely dropped...
- divstages.append(FPDivStage1Mod(self.width, self.pspec))
+ divstages.append(FPDivStage1Mod(self.pspec))
# ... and replaced with this.
# vvvvvvv
class FPDivStagesFinal(FPState, SimpleHandshake):
- def __init__(self, width, pspec, n_stages):
+ def __init__(self, pspec, n_stages):
FPState.__init__(self, "divfinal")
- self.width = width
self.pspec = pspec
self.n_stages = n_stages # number of combinatorial stages
SimpleHandshake.__init__(self, self) # pipeline is its own stage
def ispec(self):
# XXX TODO: replace with "intermediary" (DivPipeInterstageData?)
- return FPDivStage0Data(self.width, self.pspec) # DIV ispec (loop)
+ return FPDivStage0Data(self.pspec) # DIV ispec (loop)
def ospec(self):
# REQUIRED. do NOT change.
- return FPAddStage1Data(self.width, self.pspec) # to post-norm
+ return FPAddStage1Data(self.pspec) # to post-norm
def setup(self, m, i):
""" links module to inputs and outputs.
# will add.
for count in range(self.n_stages): # number of combinatorial stages
# XXX: this can actually be entirely dropped...
- divstages.append(FPDivStage1Mod(self.width, self.pspec))
+ divstages.append(FPDivStage1Mod(self.pspec))
# ... and replaced with this.
# vvvvvvv
# does conversion from DivPipeOutputData into
# FPAddStage1Data format (bad name, TODO, doesn't matter),
# so that post-normalisation and corrections can take over
- divstages.append(FPDivStage2Mod(self.width, self.pspec))
+ divstages.append(FPDivStage2Mod(self.pspec))
chain = StageChain(divstages)
chain.setup(m, i)
class FPDIVBasePipe(ControlBase):
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
ControlBase.__init__(self)
- self.width = width
self.pspec = pspec
def elaborate(self, platform):
else:
kls = FPDivStagesIntermediate
- pipechain.append(kls(self.width, self.pspec, n_comb_stages))
+ pipechain.append(kls(self.pspec, n_comb_stages))
# start and end: unpack/specialcases then normalisation/packing
- pipestart = FPDIVSpecialCasesDeNorm(self.width, self.pspec)
- pipeend = FPNormToPack(self.width, self.pspec)
+ pipestart = FPDIVSpecialCasesDeNorm(self.pspec)
+ pipeend = FPNormToPack(self.pspec)
# add submodules
m.submodules.scnorm = pipestart
then be used to change the behaviour of the pipeline.
"""
def __init__(self, width, num_rows, op_wid=0):
- self.width = width
self.id_wid = num_bits(width)
- self.pspec = {'id_wid': self.id_wid, 'op_wid': op_wid}
- self.alu = FPDIVBasePipe(width, self.pspec)
+ self.pspec = {'width': width, 'id_wid': self.id_wid, 'op_wid': op_wid}
+ self.alu = FPDIVBasePipe(self.pspec)
ReservationStations.__init__(self, num_rows)
def i_specfn(self):
- return FPADDBaseData(self.width, self.pspec)
+ return FPADDBaseData(self.pspec)
def o_specfn(self):
- return FPPackData(self.width, self.pspec)
+ return FPPackData(self.pspec)
https://steve.hollasch.net/cgindex/coding/ieeefloat.html
"""
- def __init__(self, width, pspec):
- self.width = width
+ def __init__(self, pspec):
self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPADDBaseData(self.width, self.pspec)
+ return FPADDBaseData(self.pspec)
def ospec(self):
- return FPSCData(self.width, self.pspec, False)
+ return FPSCData(self.pspec, False)
def setup(self, m, i):
""" links module to inputs and outputs
#m.submodules.sc_out_z = self.o.z
# decode: XXX really should move to separate stage
- a1 = FPNumBaseRecord(self.width, False)
- b1 = FPNumBaseRecord(self.width, False)
+ a1 = FPNumBaseRecord(self.pspec['width'], False)
+ b1 = FPNumBaseRecord(self.pspec['width'], False)
m.submodules.sc_decode_a = a1 = FPNumDecode(None, a1)
m.submodules.sc_decode_b = b1 = FPNumDecode(None, b1)
m.d.comb += [a1.v.eq(self.i.a),
https://steve.hollasch.net/cgindex/coding/ieeefloat.html
"""
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
FPState.__init__(self, "special_cases")
- self.mod = FPDIVSpecialCasesMod(width)
+ self.mod = FPDIVSpecialCasesMod(pspec)
self.out_z = self.mod.ospec()
self.out_do_z = Signal(reset_less=True)
""" special cases: NaNs, infs, zeros, denormalised
"""
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
FPState.__init__(self, "special_cases")
- self.width = width
self.pspec = pspec
SimpleHandshake.__init__(self, self) # pipe is its own stage
self.out = self.ospec()
def ispec(self):
- return FPADDBaseData(self.width, self.pspec) # SpecialCases ispec
+ return FPADDBaseData(self.pspec) # SpecialCases ispec
def ospec(self):
- return FPSCData(self.width, self.pspec, False) # DeNorm ospec
+ return FPSCData(self.pspec, False) # DeNorm ospec
def setup(self, m, i):
""" links module to inputs and outputs
"""
- smod = FPDIVSpecialCasesMod(self.width, self.pspec)
- dmod = FPAddDeNormMod(self.width, self.pspec, False)
+ smod = FPDIVSpecialCasesMod(self.pspec)
+ dmod = FPAddDeNormMod(self.pspec, False)
chain = StageChain([smod, dmod])
chain.setup(m, i)
class FPMulStage0Data:
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
+ width = pspec['width']
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 = FPPipeContext(width, pspec)
+ self.ctx = FPPipeContext(pspec)
self.muxid = self.ctx.muxid
def eq(self, i):
class FPMulStage0Mod(Elaboratable):
- def __init__(self, width, pspec):
- self.width = width
+ def __init__(self, pspec):
self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPSCData(self.width, self.pspec, False)
+ return FPSCData(self.pspec, False)
def ospec(self):
- return FPMulStage0Data(self.width, self.pspec)
+ return FPMulStage0Data(self.pspec)
def process(self, i):
return self.o
""" Second stage of mul: preparation for normalisation.
"""
- def __init__(self, width, pspec):
- self.width = width
+ def __init__(self, pspec):
self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPMulStage0Data(self.width, self.pspec)
+ return FPMulStage0Data(self.pspec)
def ospec(self):
- return FPAddStage1Data(self.width, self.pspec)
+ return FPAddStage1Data(self.pspec)
def process(self, i):
return self.o
class FPMulStage1(FPState):
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
FPState.__init__(self, "multiply_1")
- self.mod = FPMulStage1Mod(width, pspec)
+ width = pspec['width']
+ self.mod = FPMulStage1Mod(pspec)
self.out_z = FPNumBaseRecord(width, False)
self.out_of = Overflow()
self.norm_stb = Signal()
class FPMulStages(FPState, SimpleHandshake):
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
FPState.__init__(self, "align")
- self.width = width
self.pspec = pspec
SimpleHandshake.__init__(self, self) # pipeline is its own stage
self.m1o = self.ospec()
def ispec(self):
- return FPSCData(self.width, self.pspec, False)
+ return FPSCData(self.pspec, False)
def ospec(self):
- return FPAddStage1Data(self.width, self.pspec)
+ return FPAddStage1Data(self.pspec)
def setup(self, m, i):
""" links module to inputs and outputs
"""
# chain MulStage0 and MulStage1
- m0mod = FPMulStage0Mod(self.width, self.pspec)
- m1mod = FPMulStage1Mod(self.width, self.pspec)
+ m0mod = FPMulStage0Mod(self.pspec)
+ m1mod = FPMulStage1Mod(self.pspec)
chain = StageChain([m0mod, m1mod])
chain.setup(m, i)
class FPMULBasePipe(ControlBase):
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
ControlBase.__init__(self)
- self.pipe1 = FPMulSpecialCasesDeNorm(width, pspec)
- self.pipe2 = FPMulStages(width, pspec)
- self.pipe3 = FPNormToPack(width, pspec)
+ self.pipe1 = FPMulSpecialCasesDeNorm(pspec)
+ self.pipe2 = FPMulStages(pspec)
+ self.pipe3 = FPNormToPack(pspec)
self._eqs = self.connect([self.pipe1, self.pipe2, self.pipe3])
Fan-in and Fan-out are combinatorial.
"""
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.pspec['id_wid'] = self.id_wid
+ self.pspec['width'] = width
self.pspec['op_wid'] = self.op_wid
- self.alu = FPMULBasePipe(width, self.pspec)
+ self.alu = FPMULBasePipe(self.pspec)
ReservationStations.__init__(self, num_rows)
def i_specfn(self):
- return FPADDBaseData(self.width, self.pspec)
+ return FPADDBaseData(self.pspec)
def o_specfn(self):
- return FPPackData(self.width, self.pspec)
+ return FPPackData(self.pspec)
https://steve.hollasch.net/cgindex/coding/ieeefloat.html
"""
- def __init__(self, width, pspec):
- self.width = width
+ def __init__(self, pspec):
self.pspec = pspec
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPADDBaseData(self.width, self.pspec)
+ return FPADDBaseData(self.pspec)
def ospec(self):
- return FPSCData(self.width, self.pspec, False)
+ return FPSCData(self.pspec, False)
def setup(self, m, i):
""" links module to inputs and outputs
#m.submodules.sc_out_z = self.o.z
# decode: XXX really should move to separate stage
- a1 = FPNumBaseRecord(self.width, False)
- b1 = FPNumBaseRecord(self.width, False)
+ width = self.pspec['width']
+ a1 = FPNumBaseRecord(width, False)
+ b1 = FPNumBaseRecord(width, False)
m.submodules.sc_decode_a = a1 = FPNumDecode(None, a1)
m.submodules.sc_decode_b = b1 = FPNumDecode(None, b1)
m.d.comb += [a1.v.eq(self.i.a),
""" special cases: NaNs, infs, zeros, denormalised
"""
- def __init__(self, width, pspec):
+ def __init__(self, pspec):
FPState.__init__(self, "special_cases")
- self.width = width
self.pspec = pspec
SimpleHandshake.__init__(self, self) # pipe is its own stage
self.out = self.ospec()
def ispec(self):
- return FPADDBaseData(self.width, self.pspec)
+ return FPADDBaseData(self.pspec)
def ospec(self):
- return FPSCData(self.width, self.pspec, False)
+ return FPSCData(self.pspec, False)
def setup(self, m, i):
""" links module to inputs and outputs
"""
- smod = FPMulSpecialCasesMod(self.width, self.pspec)
- dmod = FPAddDeNormMod(self.width, self.pspec, False)
+ smod = FPMulSpecialCasesMod(self.pspec)
+ dmod = FPAddDeNormMod(self.pspec, False)
chain = StageChain([smod, dmod])
chain.setup(m, i)