1 # IEEE Floating Point Adder (Single Precision)
2 # Copyright (C) Jonathan P Dawson 2013
5 from nmigen
import Module
, Signal
, Cat
, Mux
, Array
, Const
6 from nmigen
.lib
.coding
import PriorityEncoder
7 from nmigen
.cli
import main
, verilog
10 from fpbase
import FPNumIn
, FPNumOut
, FPOp
, Overflow
, FPBase
, FPNumBase
11 from fpbase
import MultiShiftRMerge
, Trigger
12 from singlepipe
import (ControlBase
, StageChain
, UnbufferedPipeline
,
14 from multipipe
import CombMuxOutPipe
15 from multipipe
import PriorityCombMuxInPipe
17 from fpbase
import FPState
, FPID
18 from fpcommon
.getop
import (FPGetOpMod
, FPGetOp
, FPNumBase2Ops
, FPADDBaseData
,
19 FPGet2OpMod
, FPGet2Op
)
20 from fpcommon
.denorm
import (FPSCData
, FPAddDeNormMod
, FPAddDeNorm
)
21 from fpcommon
.postcalc
import FPAddStage1Data
22 from fpcommon
.postnormalise
import (FPNorm1Data
, FPNorm1ModSingle
,
23 FPNorm1ModMulti
, FPNorm1Single
, FPNorm1Multi
)
24 from fpcommon
.roundz
import (FPRoundData
, FPRoundMod
, FPRound
)
25 from fpcommon
.corrections
import (FPCorrectionsMod
, FPCorrections
)
26 from fpcommon
.pack
import (FPPackData
, FPPackMod
, FPPack
)
27 from fpcommon
.normtopack
import FPNormToPack
28 from fpcommon
.putz
import (FPPutZ
, FPPutZIdx
)
30 from fpadd
.specialcases
import (FPAddSpecialCasesMod
, FPAddSpecialCases
,
31 FPAddSpecialCasesDeNorm
)
32 from fpadd
.align
import (FPAddAlignMulti
, FPAddAlignMultiMod
, FPNumIn2Ops
,
33 FPAddAlignSingleMod
, FPAddAlignSingle
)
34 from fpadd
.add0
import (FPAddStage0Data
, FPAddStage0Mod
, FPAddStage0
)
35 from fpadd
.add1
import (FPAddStage1Mod
, FPAddStage1
)
36 from fpadd
.addstages
import FPAddAlignSingleAdd
39 class FPADDBasePipe(ControlBase
):
40 def __init__(self
, width
, id_wid
):
41 ControlBase
.__init
__(self
)
42 self
.pipe1
= FPAddSpecialCasesDeNorm(width
, id_wid
)
43 self
.pipe2
= FPAddAlignSingleAdd(width
, id_wid
)
44 self
.pipe3
= FPNormToPack(width
, id_wid
)
46 self
._eqs
= self
.connect([self
.pipe1
, self
.pipe2
, self
.pipe3
])
48 def elaborate(self
, platform
):
50 m
.submodules
.scnorm
= self
.pipe1
51 m
.submodules
.addalign
= self
.pipe2
52 m
.submodules
.normpack
= self
.pipe3
57 class FPADDInMuxPipe(PriorityCombMuxInPipe
):
58 def __init__(self
, width
, id_wid
, num_rows
):
59 self
.num_rows
= num_rows
60 def iospec(): return FPADDBaseData(width
, id_wid
)
61 stage
= PassThroughStage(iospec
)
62 PriorityCombMuxInPipe
.__init
__(self
, stage
, p_len
=self
.num_rows
)
65 class FPADDMuxOutPipe(CombMuxOutPipe
):
66 def __init__(self
, width
, id_wid
, num_rows
):
67 self
.num_rows
= num_rows
68 def iospec(): return FPPackData(width
, id_wid
)
69 stage
= PassThroughStage(iospec
)
70 CombMuxOutPipe
.__init
__(self
, stage
, n_len
=self
.num_rows
)
74 """ Reservation-Station version of FPADD pipeline.
76 * fan-in on inputs (an array of FPADDBaseData: a,b,mid)
77 * 3-stage adder pipeline
78 * fan-out on outputs (an array of FPPackData: z,mid)
80 Fan-in and Fan-out are combinatorial.
82 def __init__(self
, width
, id_wid
, num_rows
):
83 self
.num_rows
= num_rows
84 self
.inpipe
= FPADDInMuxPipe(width
, id_wid
, num_rows
) # fan-in
85 self
.fpadd
= FPADDBasePipe(width
, id_wid
) # add stage
86 self
.outpipe
= FPADDMuxOutPipe(width
, id_wid
, num_rows
) # fan-out
88 self
.p
= self
.inpipe
.p
# kinda annoying,
89 self
.n
= self
.outpipe
.n
# use pipe in/out as this class in/out
90 self
._ports
= self
.inpipe
.ports() + self
.outpipe
.ports()
92 def elaborate(self
, platform
):
94 m
.submodules
.inpipe
= self
.inpipe
95 m
.submodules
.fpadd
= self
.fpadd
96 m
.submodules
.outpipe
= self
.outpipe
98 m
.d
.comb
+= self
.inpipe
.n
.connect_to_next(self
.fpadd
.p
)
99 m
.d
.comb
+= self
.fpadd
.connect_to_next(self
.outpipe
)