from ieee754.fpcommon.fpbase import (FPNumBaseRecord, Overflow)
from ieee754.fpcommon.fpbase import FPState
from ieee754.fpcommon.denorm import FPSCData
+from ieee754.fpcommon.getop import FPBaseData
class FPDivStage0Data:
- 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.of = Overflow()
+ self.ctx = FPBaseData(width, pspec) # context: muxid, operator etc.
+ self.mid = self.ctx.mid # annoying. complicated.
+
# TODO: here is where Q and R would be put, and passed
# down to Stage1 processing.
mw = (self.z.m_width)*2 - 1 + 3 # sticky/round/guard bits + (2*mant) - 1
self.product = Signal(mw, reset_less=True)
- self.mid = Signal(id_wid, reset_less=True)
-
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.of.eq(i.of),
- self.product.eq(i.product), self.mid.eq(i.mid)]
+ self.product.eq(i.product), self.ctx.eq(i.ctx)]
class FPDivStage0Mod(Elaboratable):
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
class FPDivStage1Mod(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 FPDivStage0Data(self.width, self.id_wid) # Q/Rem (etc) in...
+ return FPDivStage0Data(self.width, self.pspec) # Q/Rem (etc) in...
def ospec(self):
- return FPDivStage0Data(self.width, self.id_wid) # ... Q/Rem (etc) out
+ return FPDivStage0Data(self.width, self.pspec) # ... Q/Rem (etc) out
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
""" Second stage of div: preparation for normalisation.
"""
- 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 FPDivStage0Data(self.width, self.id_wid) # Q/Rem in...
+ return FPDivStage0Data(self.width, self.pspec) # Q/Rem in...
def ospec(self):
- return FPAddStage1Data(self.width, self.id_wid) # out to post-process
+ return FPAddStage1Data(self.width, self.pspec) # out to post-process
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 FPDivStage2(FPState):
- def __init__(self, width, id_wid):
+ def __init__(self, width, pspec):
FPState.__init__(self, "divider_1")
self.mod = FPDivStage2Mod(width)
self.out_z = FPNumBaseRecord(width, False)
class FPDivStages(FPState, SimpleHandshake):
- def __init__(self, width, id_wid, n_stages, begin, end):
+ def __init__(self, width, pspec, n_stages, begin, end):
FPState.__init__(self, "align")
self.width = width
- self.id_wid = id_wid
+ self.pspec = pspec
self.n_stages = n_stages # number of combinatorial stages
self.begin = begin # "begin" mode
self.end = end # "end" mode
def ispec(self):
if self.begin:
- return FPSCData(self.width, self.id_wid, False) # from denorm
- return FPDivStage0Data(self.width, self.id_wid) # DIV ispec (loop)
+ return FPSCData(self.width, self.pspec, False) # from denorm
+ return FPDivStage0Data(self.width, self.pspec) # DIV ispec (loop)
def ospec(self):
if self.end: # TODO
- return FPAddStage1Data(self.width, self.id_wid) # to post-norm
- return FPDivStage0Data(self.width, self.id_wid) # DIV ospec (loop)
+ return FPAddStage1Data(self.width, self.pspec) # to post-norm
+ return FPDivStage0Data(self.width, self.pspec) # DIV ospec (loop)
def setup(self, m, i):
""" links module to inputs and outputs
divstages = []
if self.begin: # XXX check this
- divstages.append(FPDivStage0Mod(self.width, self.id_wid))
+ divstages.append(FPDivStage0Mod(self.width, self.pspec))
for count in range(self.n_stages): # number of combinatorial stages
- divstages.append(FPDivStage1Mod(self.width, self.id_wid))
+ divstages.append(FPDivStage1Mod(self.width, self.pspec))
if self.end: # XXX check this
- divstages.append(FPDivStage2Mod(self.width, self.id_wid))
+ divstages.append(FPDivStage2Mod(self.width, self.pspec))
chain = StageChain(divstages)
chain.setup(m, i)
class FPDIVBasePipe(ControlBase):
- def __init__(self, width, id_wid):
+ def __init__(self, width, pspec):
ControlBase.__init__(self)
- self.pipestart = FPDIVSpecialCasesDeNorm(width, id_wid)
+ self.pipestart = FPDIVSpecialCasesDeNorm(width, pspec)
pipechain = []
n_stages = 6 # TODO
n_combinatorial_stages = 2 # TODO
for i in range(n_stages):
begin = i == 0 # needs to convert input from pipestart ospec
end = i == n_stages - 1 # needs to convert output to pipeend ispec
- pipechain.append(FPDivStages(width, id_wid,
+ pipechain.append(FPDivStages(width, pspec,
n_combinatorial_stages,
begin, end))
self.pipechain = pipechain
- self.pipeend = FPNormToPack(width, id_wid)
+ self.pipeend = FPNormToPack(width, pspec)
self._eqs = self.connect([self.pipestart] + pipechain + [self.pipeend])
Fan-in and Fan-out are combinatorial.
"""
- def __init__(self, width, num_rows):
+ def __init__(self, width, num_rows, op_wid=0):
self.width = width
self.id_wid = num_bits(width)
- self.alu = FPDIVBasePipe(width, self.id_wid)
+ self.pspec = {'id_wid': self.id_wid, 'op_wid': op_wid}
+ self.alu = FPDIVBasePipe(width, self.pspec)
ReservationStations.__init__(self, num_rows)
def i_specfn(self):
- return FPADDBaseData(self.width, self.id_wid)
+ return FPADDBaseData(self.width, self.pspec)
def o_specfn(self):
- return FPPackData(self.width, self.id_wid)
+ return FPPackData(self.width, self.pspec)
https://steve.hollasch.net/cgindex/coding/ieeefloat.html
"""
- 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 FPADDBaseData(self.width, self.id_wid)
+ return FPADDBaseData(self.width, self.pspec)
def ospec(self):
- return FPSCData(self.width, self.id_wid, False)
+ return FPSCData(self.width, self.pspec, False)
def setup(self, m, i):
""" links module to inputs and outputs
https://steve.hollasch.net/cgindex/coding/ieeefloat.html
"""
- def __init__(self, width, id_wid):
+ def __init__(self, width, pspec):
FPState.__init__(self, "special_cases")
self.mod = FPDIVSpecialCasesMod(width)
self.out_z = self.mod.ospec()
""" special cases: NaNs, infs, zeros, denormalised
"""
- def __init__(self, width, id_wid):
+ def __init__(self, width, pspec):
FPState.__init__(self, "special_cases")
self.width = width
- self.id_wid = id_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) # SpecialCases ispec
+ return FPADDBaseData(self.width, self.pspec) # SpecialCases ispec
def ospec(self):
- return FPSCData(self.width, self.id_wid, False) # DeNorm ospec
+ return FPSCData(self.width, self.pspec, False) # DeNorm ospec
def setup(self, m, i):
""" links module to inputs and outputs
"""
- smod = FPDIVSpecialCasesMod(self.width, self.id_wid)
- dmod = FPAddDeNormMod(self.width, self.id_wid, False)
+ smod = FPDIVSpecialCasesMod(self.width, self.pspec)
+ dmod = FPAddDeNormMod(self.width, self.pspec, False)
chain = StageChain([smod, dmod])
chain.setup(m, i)