1 # IEEE Floating Point Adder (Single Precision)
2 # Copyright (C) Jonathan P Dawson 2013
5 from nmigen
import Module
6 from nmigen
.cli
import main
, verilog
8 from singlepipe
import (ControlBase
, UnbufferedPipeline
, PassThroughStage
)
9 from multipipe
import CombMuxOutPipe
10 from multipipe
import PriorityCombMuxInPipe
12 from fpcommon
.getop
import FPADDBaseData
13 from fpcommon
.denorm
import FPSCData
14 from fpcommon
.pack
import FPPackData
15 from fpcommon
.normtopack
import FPNormToPack
16 from fpadd
.specialcases
import FPAddSpecialCasesDeNorm
17 from fpadd
.addstages
import FPAddAlignSingleAdd
20 class FPADDBasePipe(ControlBase
):
21 def __init__(self
, width
, id_wid
):
22 ControlBase
.__init
__(self
)
23 self
.pipe1
= FPAddSpecialCasesDeNorm(width
, id_wid
)
24 self
.pipe2
= FPAddAlignSingleAdd(width
, id_wid
)
25 self
.pipe3
= FPNormToPack(width
, id_wid
)
27 self
._eqs
= self
.connect([self
.pipe1
, self
.pipe2
, self
.pipe3
])
29 def elaborate(self
, platform
):
31 m
.submodules
.scnorm
= self
.pipe1
32 m
.submodules
.addalign
= self
.pipe2
33 m
.submodules
.normpack
= self
.pipe3
38 class FPADDInMuxPipe(PriorityCombMuxInPipe
):
39 def __init__(self
, width
, id_wid
, num_rows
):
40 self
.num_rows
= num_rows
41 def iospec(): return FPADDBaseData(width
, id_wid
)
42 stage
= PassThroughStage(iospec
)
43 PriorityCombMuxInPipe
.__init
__(self
, stage
, p_len
=self
.num_rows
)
46 class FPADDMuxOutPipe(CombMuxOutPipe
):
47 def __init__(self
, width
, id_wid
, num_rows
):
48 self
.num_rows
= num_rows
49 def iospec(): return FPPackData(width
, id_wid
)
50 stage
= PassThroughStage(iospec
)
51 CombMuxOutPipe
.__init
__(self
, stage
, n_len
=self
.num_rows
)
55 """ Reservation-Station version of FPADD pipeline.
57 * fan-in on inputs (an array of FPADDBaseData: a,b,mid)
58 * 3-stage adder pipeline
59 * fan-out on outputs (an array of FPPackData: z,mid)
61 Fan-in and Fan-out are combinatorial.
63 def __init__(self
, width
, id_wid
, num_rows
):
64 self
.num_rows
= num_rows
65 self
.inpipe
= FPADDInMuxPipe(width
, id_wid
, num_rows
) # fan-in
66 self
.fpadd
= FPADDBasePipe(width
, id_wid
) # add stage
67 self
.outpipe
= FPADDMuxOutPipe(width
, id_wid
, num_rows
) # fan-out
69 self
.p
= self
.inpipe
.p
# kinda annoying,
70 self
.n
= self
.outpipe
.n
# use pipe in/out as this class in/out
71 self
._ports
= self
.inpipe
.ports() + self
.outpipe
.ports()
73 def elaborate(self
, platform
):
75 m
.submodules
.inpipe
= self
.inpipe
76 m
.submodules
.fpadd
= self
.fpadd
77 m
.submodules
.outpipe
= self
.outpipe
79 m
.d
.comb
+= self
.inpipe
.n
.connect_to_next(self
.fpadd
.p
)
80 m
.d
.comb
+= self
.fpadd
.connect_to_next(self
.outpipe
)