From: Luke Kenneth Casson Leighton Date: Tue, 2 Jul 2019 08:41:45 +0000 (+0100) Subject: convert fpdiv to pspec X-Git-Tag: ls180-24jan2020~947 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=77e63a44e030e99cca7735afcb48584b79a50557;p=ieee754fpu.git convert fpdiv to pspec --- diff --git a/src/ieee754/fpdiv/div0.py b/src/ieee754/fpdiv/div0.py index 0667639d..330d5af5 100644 --- a/src/ieee754/fpdiv/div0.py +++ b/src/ieee754/fpdiv/div0.py @@ -9,28 +9,30 @@ from nmigen.cli import main, verilog 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): @@ -86,7 +88,7 @@ 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 diff --git a/src/ieee754/fpdiv/div1.py b/src/ieee754/fpdiv/div1.py index 9dfb7cd6..dd2aba48 100644 --- a/src/ieee754/fpdiv/div1.py +++ b/src/ieee754/fpdiv/div1.py @@ -14,17 +14,17 @@ from .div0 import FPDivStage0Data 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 @@ -64,6 +64,6 @@ class FPDivStage1Mod(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 diff --git a/src/ieee754/fpdiv/div2.py b/src/ieee754/fpdiv/div2.py index 1b54db47..9c77667a 100644 --- a/src/ieee754/fpdiv/div2.py +++ b/src/ieee754/fpdiv/div2.py @@ -15,17 +15,17 @@ class FPDivStage2Mod(FPState, Elaboratable): """ 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 @@ -65,14 +65,14 @@ class FPDivStage2Mod(FPState, Elaboratable): 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) diff --git a/src/ieee754/fpdiv/divstages.py b/src/ieee754/fpdiv/divstages.py index 8e33ba8e..2dac2a62 100644 --- a/src/ieee754/fpdiv/divstages.py +++ b/src/ieee754/fpdiv/divstages.py @@ -22,10 +22,10 @@ from .div0 import FPDivStage0Data 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 @@ -34,13 +34,13 @@ class FPDivStages(FPState, SimpleHandshake): 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 @@ -59,13 +59,13 @@ class FPDivStages(FPState, SimpleHandshake): 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) diff --git a/src/ieee754/fpdiv/pipeline.py b/src/ieee754/fpdiv/pipeline.py index b171db27..8af7ba83 100644 --- a/src/ieee754/fpdiv/pipeline.py +++ b/src/ieee754/fpdiv/pipeline.py @@ -54,20 +54,20 @@ from .divstages import FPDivStages 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]) @@ -90,14 +90,15 @@ class FPDIVMuxInOut(ReservationStations): 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) diff --git a/src/ieee754/fpdiv/specialcases.py b/src/ieee754/fpdiv/specialcases.py index 5ec31949..b7a05047 100644 --- a/src/ieee754/fpdiv/specialcases.py +++ b/src/ieee754/fpdiv/specialcases.py @@ -18,17 +18,17 @@ class FPDIVSpecialCasesMod(Elaboratable): 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 @@ -113,7 +113,7 @@ class FPDIVSpecialCases(FPState): 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() @@ -138,24 +138,24 @@ class FPDIVSpecialCasesDeNorm(FPState, SimpleHandshake): """ 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)