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 singlepipe
import (ControlBase
, UnbufferedPipeline
, PassThroughStage
)
11 from multipipe
import CombMuxOutPipe
12 from multipipe
import PriorityCombMuxInPipe
14 from fpcommon
.getop
import FPADDBaseData
15 from fpcommon
.denorm
import FPSCData
16 from fpcommon
.pack
import FPPackData
17 from fpcommon
.normtopack
import FPNormToPack
18 from fpadd
.specialcases
import FPAddSpecialCasesDeNorm
19 from fpadd
.addstages
import FPAddAlignSingleAdd
22 class FPADDBasePipe(ControlBase
):
23 def __init__(self
, width
, id_wid
):
24 ControlBase
.__init
__(self
)
25 self
.pipe1
= FPAddSpecialCasesDeNorm(width
, id_wid
)
26 self
.pipe2
= FPAddAlignSingleAdd(width
, id_wid
)
27 self
.pipe3
= FPNormToPack(width
, id_wid
)
29 self
._eqs
= self
.connect([self
.pipe1
, self
.pipe2
, self
.pipe3
])
31 def elaborate(self
, platform
):
33 m
.submodules
.scnorm
= self
.pipe1
34 m
.submodules
.addalign
= self
.pipe2
35 m
.submodules
.normpack
= self
.pipe3
40 class FPADDInMuxPipe(PriorityCombMuxInPipe
):
41 def __init__(self
, width
, id_wid
, num_rows
):
42 self
.num_rows
= num_rows
43 def iospec(): return FPADDBaseData(width
, id_wid
)
44 stage
= PassThroughStage(iospec
)
45 PriorityCombMuxInPipe
.__init
__(self
, stage
, p_len
=self
.num_rows
)
48 class FPADDMuxOutPipe(CombMuxOutPipe
):
49 def __init__(self
, width
, id_wid
, num_rows
):
50 self
.num_rows
= num_rows
51 def iospec(): return FPPackData(width
, id_wid
)
52 stage
= PassThroughStage(iospec
)
53 CombMuxOutPipe
.__init
__(self
, stage
, n_len
=self
.num_rows
)
57 """ Reservation-Station version of FPADD pipeline.
59 * fan-in on inputs (an array of FPADDBaseData: a,b,mid)
60 * 3-stage adder pipeline
61 * fan-out on outputs (an array of FPPackData: z,mid)
63 Fan-in and Fan-out are combinatorial.
65 def __init__(self
, width
, id_wid
, num_rows
):
66 self
.num_rows
= num_rows
67 self
.inpipe
= FPADDInMuxPipe(width
, id_wid
, num_rows
) # fan-in
68 self
.fpadd
= FPADDBasePipe(width
, id_wid
) # add stage
69 self
.outpipe
= FPADDMuxOutPipe(width
, id_wid
, num_rows
) # fan-out
71 self
.p
= self
.inpipe
.p
# kinda annoying,
72 self
.n
= self
.outpipe
.n
# use pipe in/out as this class in/out
73 self
._ports
= self
.inpipe
.ports() + self
.outpipe
.ports()
75 def elaborate(self
, platform
):
77 m
.submodules
.inpipe
= self
.inpipe
78 m
.submodules
.fpadd
= self
.fpadd
79 m
.submodules
.outpipe
= self
.outpipe
81 m
.d
.comb
+= self
.inpipe
.n
.connect_to_next(self
.fpadd
.p
)
82 m
.d
.comb
+= self
.fpadd
.connect_to_next(self
.outpipe
)