From: Jacob Lifshay Date: Sun, 14 Jul 2019 07:13:39 +0000 (-0700) Subject: switch pspec from dict to PipelineSpec X-Git-Tag: ls180-24jan2020~848 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=df480a81912c4dca0fa4c9fa281d635e925624f6;p=ieee754fpu.git switch pspec from dict to PipelineSpec --- diff --git a/src/ieee754/div_rem_sqrt_rsqrt/div_pipe.py b/src/ieee754/div_rem_sqrt_rsqrt/div_pipe.py index aa0b9f90..7daac8a9 100644 --- a/src/ieee754/div_rem_sqrt_rsqrt/div_pipe.py +++ b/src/ieee754/div_rem_sqrt_rsqrt/div_pipe.py @@ -39,7 +39,7 @@ class DivPipeBaseData: def __init__(self, config): """ Create a ``DivPipeBaseData`` instance. """ self.config = config - width = config.pspec['width'] + width = config.pspec.width self.out_do_z = Signal(reset_less=True) self.oz = Signal(width, reset_less=True) diff --git a/src/ieee754/fcvt/pipeline.py b/src/ieee754/fcvt/pipeline.py index 378855a0..4178629e 100644 --- a/src/ieee754/fcvt/pipeline.py +++ b/src/ieee754/fcvt/pipeline.py @@ -29,6 +29,7 @@ from nmutil.singlepipe import SimpleHandshake, StageChain from ieee754.fpcommon.fpbase import FPState, FPID from ieee754.fpcommon.getop import FPADDBaseData +from ieee754.pipeline import PipelineSpec class FPCVTSpecialCasesMod(Elaboratable): @@ -64,18 +65,18 @@ class FPCVTSpecialCasesMod(Elaboratable): #m.submodules.sc_out_z = self.o.z # decode: XXX really should move to separate stage - print ("in_width out", self.in_pspec['width'], - self.out_pspec['width']) - a1 = FPNumBaseRecord(self.in_pspec['width'], False) - print ("a1", a1.width, a1.rmw, a1.e_width, a1.e_start, a1.e_end) + print("in_width out", self.in_pspec.width, + self.out_pspec.width) + a1 = FPNumBaseRecord(self.in_pspec.width, False) + print("a1", a1.width, a1.rmw, a1.e_width, a1.e_start, a1.e_end) m.submodules.sc_decode_a = a1 = FPNumDecode(None, a1) m.d.comb += a1.v.eq(self.i.a) z1 = self.o.z - print ("z1", z1.width, z1.rmw, z1.e_width, z1.e_start, z1.e_end) + print("z1", z1.width, z1.rmw, z1.e_width, z1.e_start, z1.e_end) me = a1.rmw ms = a1.rmw - self.o.z.rmw - print ("ms-me", ms, me) + print("ms-me", ms, me) # intermediaries exp_sub_n126 = Signal((a1.e_width, True), reset_less=True) @@ -96,7 +97,7 @@ class FPCVTSpecialCasesMod(Elaboratable): m.d.comb += self.o.of.guard.eq(a1.m[ms-1]) m.d.comb += self.o.of.round_bit.eq(a1.m[ms-2]) m.d.comb += self.o.of.sticky.eq(a1.m[:ms-2].bool()) - m.d.comb += self.o.of.m0.eq(a1.m[ms]) # bit of a1 + m.d.comb += self.o.of.m0.eq(a1.m[ms]) # bit of a1 m.d.comb += self.o.z.s.eq(a1.s) m.d.comb += self.o.z.e.eq(a1.e) @@ -115,7 +116,7 @@ class FPCVTSpecialCasesMod(Elaboratable): # if a mantissa greater than 127, return inf with m.Elif(exp_gt127): - print ("inf", self.o.z.inf(a1.s)) + print("inf", self.o.z.inf(a1.s)) m.d.comb += self.o.z.inf(a1.s) m.d.comb += self.o.out_do_z.eq(1) @@ -124,15 +125,15 @@ class FPCVTSpecialCasesMod(Elaboratable): m.d.comb += self.o.of.guard.eq(a1.m[ms-1]) m.d.comb += self.o.of.round_bit.eq(a1.m[ms-2]) m.d.comb += self.o.of.sticky.eq(a1.m[:ms-2].bool()) - m.d.comb += self.o.of.m0.eq(a1.m[ms]) # bit of a1 + m.d.comb += self.o.of.m0.eq(a1.m[ms]) # bit of a1 # XXX TODO: this is basically duplicating FPRoundMod. hmmm... - print ("alen", a1.e_start, z1.fp.N126, N126) - print ("m1", self.o.z.rmw, a1.m[-self.o.z.rmw-1:]) + print("alen", a1.e_start, z1.fp.N126, N126) + print("m1", self.o.z.rmw, a1.m[-self.o.z.rmw-1:]) mo = Signal(self.o.z.m_width-1) m.d.comb += mo.eq(a1.m[ms:me]) with m.If(self.o.of.roundz): - with m.If((~mo == 0)): # all 1s + with m.If((~mo == 0)): # all 1s m.d.comb += self.o.z.create(a1.s, a1.e+1, mo+1) with m.Else(): m.d.comb += self.o.z.create(a1.s, a1.e, mo+1) @@ -161,7 +162,7 @@ class FPCVTSpecialCases(FPState): """ links module to inputs and outputs """ 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.v.eq(self.mod.out_z.v) # only take the output m.d.sync += self.out_z.ctx.eq(self.mod.o.ctx) # (and context) def action(self, m): @@ -208,20 +209,14 @@ class FPCVTMuxInOut(ReservationStations): Fan-in and Fan-out are combinatorial. """ + def __init__(self, in_width, out_width, num_rows, op_wid=0): 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'] = in_width - - self.out_pspec = {} - self.out_pspec['id_wid'] = self.out_id_wid - self.out_pspec['op_wid'] = op_wid - self.out_pspec['width'] = out_width + self.in_pspec = PipelineSpec(in_width, self.id_wid, self.op_wid) + self.out_pspec = PipelineSpec(out_width, self.out_id_wid, op_wid) self.alu = FPCVTBasePipe(self.in_pspec, self.out_pspec) ReservationStations.__init__(self, num_rows) diff --git a/src/ieee754/fpadd/add0.py b/src/ieee754/fpadd/add0.py index e5a683da..c56b035d 100644 --- a/src/ieee754/fpadd/add0.py +++ b/src/ieee754/fpadd/add0.py @@ -14,7 +14,7 @@ from ieee754.fpcommon.getop import FPPipeContext class FPAddStage0Data: def __init__(self, pspec): - width = pspec['width'] + width = pspec.width self.z = FPNumBaseRecord(width, False) self.out_do_z = Signal(reset_less=True) self.oz = Signal(width, reset_less=True) diff --git a/src/ieee754/fpadd/align.py b/src/ieee754/fpadd/align.py index 1db5affa..5ffe1a62 100644 --- a/src/ieee754/fpadd/align.py +++ b/src/ieee754/fpadd/align.py @@ -16,7 +16,7 @@ from ieee754.fpcommon.getop import FPPipeContext class FPNumIn2Ops: def __init__(self, pspec): - width = pspec['width'] + width = pspec.width self.a = FPNumBaseRecord(width) self.b = FPNumBaseRecord(width) self.z = FPNumBaseRecord(width, False) @@ -136,7 +136,7 @@ class FPAddAlignSingleMod(Elaboratable): #m.submodules.align_out_b = self.o.b # temporary (muxed) input and output to be shifted - width = self.pspec['width'] + width = self.pspec.width t_inp = FPNumBaseRecord(width) t_out = FPNumBaseRecord(width) espec = (len(self.i.a.e), True) @@ -196,7 +196,7 @@ class FPAddAlignSingle(FPState): def __init__(self, pspec): FPState.__init__(self, "align") - width = pspec['width'] + width = pspec.width self.mod = FPAddAlignSingleMod(pspec) self.out_a = FPNumIn(None, width) self.out_b = FPNumIn(None, width) diff --git a/src/ieee754/fpadd/pipeline.py b/src/ieee754/fpadd/pipeline.py index bee4cf3f..9a7820f7 100644 --- a/src/ieee754/fpadd/pipeline.py +++ b/src/ieee754/fpadd/pipeline.py @@ -16,7 +16,7 @@ from ieee754.fpcommon.pack import FPPackData from ieee754.fpcommon.normtopack import FPNormToPack from .specialcases import FPAddSpecialCasesDeNorm from .addstages import FPAddAlignSingleAdd - +from ieee754.pipeline import PipelineSpec class FPADDBasePipe(ControlBase): @@ -46,10 +46,11 @@ class FPADDMuxInOut(ReservationStations): Fan-in and Fan-out are combinatorial. """ + def __init__(self, width, num_rows, op_wid=None): self.id_wid = num_bits(width) self.op_wid = op_wid - self.pspec = {'width': width, 'id_wid': self.id_wid, 'op_wid': op_wid} + self.pspec = PipelineSpec(width, self.id_wid, op_wid) self.alu = FPADDBasePipe(self.pspec) ReservationStations.__init__(self, num_rows) diff --git a/src/ieee754/fpadd/specialcases.py b/src/ieee754/fpadd/specialcases.py index b6eb1a47..1ae338d0 100644 --- a/src/ieee754/fpadd/specialcases.py +++ b/src/ieee754/fpadd/specialcases.py @@ -46,7 +46,7 @@ class FPAddSpecialCasesMod(Elaboratable): #m.submodules.sc_out_z = self.o.z # decode: XXX really should move to separate stage - width = self.pspec['width'] + width = self.pspec.width a1 = FPNumBaseRecord(width) b1 = FPNumBaseRecord(width) m.submodules.sc_decode_a = a1 = FPNumDecode(None, a1) diff --git a/src/ieee754/fpcommon/denorm.py b/src/ieee754/fpcommon/denorm.py index 58621369..ef1acb6d 100644 --- a/src/ieee754/fpcommon/denorm.py +++ b/src/ieee754/fpcommon/denorm.py @@ -14,7 +14,7 @@ from ieee754.fpcommon.getop import FPPipeContext class FPSCData: def __init__(self, pspec, m_extra): - width = pspec['width'] + 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* diff --git a/src/ieee754/fpcommon/getop.py b/src/ieee754/fpcommon/getop.py index 8f580c1f..27f677c7 100644 --- a/src/ieee754/fpcommon/getop.py +++ b/src/ieee754/fpcommon/getop.py @@ -91,7 +91,7 @@ class FPPipeContext: "operator". instance must have an "eq" function. """ - self.id_wid = pspec['id_wid'] + self.id_wid = pspec.id_width self.op_wid = pspec.get('op_wid', 0) self.muxid = Signal(self.id_wid, reset_less=True) # RS multiplex ID opkls = pspec.get('opkls', None) @@ -116,7 +116,7 @@ class FPPipeContext: class FPADDBaseData: def __init__(self, pspec, n_ops=2): - width = pspec['width'] + width = pspec.width self.ctx = FPPipeContext(pspec) ops = [] for i in range(n_ops): diff --git a/src/ieee754/fpcommon/pack.py b/src/ieee754/fpcommon/pack.py index 529dd51b..1240ca62 100644 --- a/src/ieee754/fpcommon/pack.py +++ b/src/ieee754/fpcommon/pack.py @@ -15,7 +15,7 @@ from ieee754.fpcommon.getop import FPPipeContext class FPPackData: def __init__(self, pspec): - width = pspec['width'] + width = pspec.width self.z = Signal(width, reset_less=True) # result self.ctx = FPPipeContext(pspec) @@ -63,7 +63,7 @@ class FPPackMod(Elaboratable): def elaborate(self, platform): m = Module() - z = FPNumBaseRecord(self.pspec['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) diff --git a/src/ieee754/fpcommon/postcalc.py b/src/ieee754/fpcommon/postcalc.py index 47c7d8d5..ce7b2736 100644 --- a/src/ieee754/fpcommon/postcalc.py +++ b/src/ieee754/fpcommon/postcalc.py @@ -9,7 +9,7 @@ from ieee754.fpcommon.getop import FPPipeContext class FPAddStage1Data: def __init__(self, pspec, e_extra=False): - width = pspec['width'] + width = pspec.width self.z = FPNumBaseRecord(width, False, e_extra) self.out_do_z = Signal(reset_less=True) self.oz = Signal(width, reset_less=True) diff --git a/src/ieee754/fpcommon/postnormalise.py b/src/ieee754/fpcommon/postnormalise.py index 2bf57278..b4c4a54d 100644 --- a/src/ieee754/fpcommon/postnormalise.py +++ b/src/ieee754/fpcommon/postnormalise.py @@ -17,7 +17,7 @@ from .postcalc import FPAddStage1Data class FPNorm1Data: def __init__(self, pspec): - width = pspec['width'] + 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) diff --git a/src/ieee754/fpcommon/roundz.py b/src/ieee754/fpcommon/roundz.py index 7704151f..9c9af127 100644 --- a/src/ieee754/fpcommon/roundz.py +++ b/src/ieee754/fpcommon/roundz.py @@ -14,7 +14,7 @@ from .postnormalise import FPNorm1Data class FPRoundData: def __init__(self, pspec): - width = pspec['width'] + width = pspec.width self.z = FPNumBaseRecord(width, False) self.ctx = FPPipeContext(pspec) self.muxid = self.ctx.muxid diff --git a/src/ieee754/fpdiv/div0.py b/src/ieee754/fpdiv/div0.py index 81166c74..8529e382 100644 --- a/src/ieee754/fpdiv/div0.py +++ b/src/ieee754/fpdiv/div0.py @@ -16,11 +16,11 @@ from ieee754.fpcommon.getop import FPPipeContext class FPDivStage0Data: def __init__(self, pspec): - self.z = FPNumBaseRecord(pspec['width'], False) + self.z = FPNumBaseRecord(pspec.width, False) self.out_do_z = Signal(reset_less=True) - self.oz = Signal(pspec['width'], reset_less=True) + self.oz = Signal(pspec.width, reset_less=True) - self.ctx = FPPipeContext(pspec['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 diff --git a/src/ieee754/fpdiv/pipeline.py b/src/ieee754/fpdiv/pipeline.py index e632a6d9..60b1689c 100644 --- a/src/ieee754/fpdiv/pipeline.py +++ b/src/ieee754/fpdiv/pipeline.py @@ -70,6 +70,7 @@ from .specialcases import FPDIVSpecialCasesDeNorm from .divstages import (FPDivStagesSetup, FPDivStagesIntermediate, FPDivStagesFinal) +from ieee754.pipeline import PipelineSpec class FPDIVBasePipe(ControlBase): @@ -82,22 +83,22 @@ class FPDIVBasePipe(ControlBase): pipechain = [] n_stages = 6 # TODO (depends on width) - n_comb_stages = 3 # TODO (depends on how many RS's we want) - # to which the answer: "as few as possible" - # is required. too many ReservationStations - # means "big problems". + n_comb_stages = 3 # TODO (depends on how many RS's we want) + # to which the answer: "as few as possible" + # is required. too many ReservationStations + # means "big problems". for i in range(n_stages): # needs to convert input from pipestart ospec if i == 0: kls = FPDivStagesSetup - n_comb_stages -= 1 # reduce due to work done at start + n_comb_stages -= 1 # reduce due to work done at start # needs to convert output to pipeend ispec elif i == n_stages - 1: kls = FPDivStagesFinal - n_comb_stages -= 1 # FIXME - reduce due to work done at end? + n_comb_stages -= 1 # FIXME - reduce due to work done at end? # intermediary stage else: @@ -133,15 +134,13 @@ class FPDIVMuxInOut(ReservationStations): :op_wid: - set this to the width of an operator which can then be used to change the behaviour of the pipeline. """ + def __init__(self, width, num_rows, op_wid=0): self.id_wid = num_bits(width) - self.pspec = {} - self.pspec['width'] = width - self.pspec['id_wid'] = self.id_wid - self.pspec['op_wid'] = op_wid + self.pspec = PipelineSpec(width, self.id_wid, op_wid) # XXX TODO - a class (or function?) that takes the pspec (right here) # and creates... "something". that "something" MUST have an eq function - # self.pspec['opkls'] = DivPipeCoreOperation + # self.pspec.opkls = DivPipeCoreOperation self.alu = FPDIVBasePipe(self.pspec) ReservationStations.__init__(self, num_rows) diff --git a/src/ieee754/fpdiv/specialcases.py b/src/ieee754/fpdiv/specialcases.py index f1704424..d039eaaf 100644 --- a/src/ieee754/fpdiv/specialcases.py +++ b/src/ieee754/fpdiv/specialcases.py @@ -44,8 +44,8 @@ class FPDIVSpecialCasesMod(Elaboratable): #m.submodules.sc_out_z = self.o.z # decode: XXX really should move to separate stage - a1 = FPNumBaseRecord(self.pspec['width'], False) - b1 = FPNumBaseRecord(self.pspec['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), diff --git a/src/ieee754/fpmul/mul0.py b/src/ieee754/fpmul/mul0.py index f56f69b5..656e9bc0 100644 --- a/src/ieee754/fpmul/mul0.py +++ b/src/ieee754/fpmul/mul0.py @@ -14,7 +14,7 @@ from ieee754.fpcommon.getop import FPPipeContext class FPMulStage0Data: def __init__(self, pspec): - width = pspec['width'] + width = pspec.width self.z = FPNumBaseRecord(width, False) self.out_do_z = Signal(reset_less=True) self.oz = Signal(width, reset_less=True) diff --git a/src/ieee754/fpmul/mul1.py b/src/ieee754/fpmul/mul1.py index 763b8722..841efcdf 100644 --- a/src/ieee754/fpmul/mul1.py +++ b/src/ieee754/fpmul/mul1.py @@ -65,7 +65,7 @@ class FPMulStage1(FPState): def __init__(self, pspec): FPState.__init__(self, "multiply_1") - width = pspec['width'] + width = pspec.width self.mod = FPMulStage1Mod(pspec) self.out_z = FPNumBaseRecord(width, False) self.norm_stb = Signal() diff --git a/src/ieee754/fpmul/pipeline.py b/src/ieee754/fpmul/pipeline.py index f146b1a7..08c151d0 100644 --- a/src/ieee754/fpmul/pipeline.py +++ b/src/ieee754/fpmul/pipeline.py @@ -14,7 +14,7 @@ from ieee754.fpcommon.pack import FPPackData from ieee754.fpcommon.normtopack import FPNormToPack from .specialcases import FPMulSpecialCasesDeNorm from .mulstages import FPMulStages - +from ieee754.pipeline import PipelineSpec class FPMULBasePipe(ControlBase): @@ -44,13 +44,11 @@ class FPMULMuxInOut(ReservationStations): Fan-in and Fan-out are combinatorial. """ + def __init__(self, width, num_rows, op_wid=0): - 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.pspec = PipelineSpec(width, self.id_wid, self.op_wid) self.alu = FPMULBasePipe(self.pspec) ReservationStations.__init__(self, num_rows) diff --git a/src/ieee754/fpmul/specialcases.py b/src/ieee754/fpmul/specialcases.py index 43fc1810..68e75d15 100644 --- a/src/ieee754/fpmul/specialcases.py +++ b/src/ieee754/fpmul/specialcases.py @@ -45,7 +45,7 @@ class FPMulSpecialCasesMod(Elaboratable): #m.submodules.sc_out_z = self.o.z # decode: XXX really should move to separate stage - width = self.pspec['width'] + width = self.pspec.width a1 = FPNumBaseRecord(width, False) b1 = FPNumBaseRecord(width, False) m.submodules.sc_decode_a = a1 = FPNumDecode(None, a1) diff --git a/src/ieee754/pipeline.py b/src/ieee754/pipeline.py new file mode 100644 index 00000000..f2ec6933 --- /dev/null +++ b/src/ieee754/pipeline.py @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# See Notices.txt for copyright information + + +class PipelineSpec: + """ Pipeline Specification base class. + + :attribute width: FIXME: document + :attribute id_width: FIXME: document + :attribute opcode_width: FIXME: document + """ + + def __init__(self, width, id_width, opcode_width): + """ Create a PipelineSpec. """ + self.width = width + self.id_width = id_width + self.opcode_width = opcode_width