1 # IEEE754 Floating Point Conversion
2 # Copyright (C) 2019 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
8 from nmigen
import Module
, Signal
, Cat
, Const
, Mux
, Elaboratable
9 from nmigen
.cli
import main
, verilog
11 from nmutil
.singlepipe
import ControlBase
12 from nmutil
.concurrentunit
import ReservationStations
, num_bits
14 from ieee754
.fpcommon
.getop
import FPADDBaseData
15 from ieee754
.fpcommon
.pack
import FPPackData
16 from ieee754
.fpcommon
.normtopack
import FPNormToPack
19 from nmigen
import Module
, Signal
, Elaboratable
22 from ieee754
.fpcommon
.getop
import FPPipeContext
24 from ieee754
.pipeline
import PipelineSpec
, DynamicPipe
26 from ieee754
.fcvt
.float2int
import FPCVTFloatToIntMod
27 from ieee754
.fcvt
.int2float
import FPCVTIntToFloatMod
28 from ieee754
.fcvt
.upsize
import FPCVTUpConvertMod
29 from ieee754
.fcvt
.downsize
import FPCVTDownConvertMod
34 self
.signed
= Signal(reset_less
=True)
37 return [self
.signed
.eq(i
)]
40 class FPCVTConvertDeNorm(DynamicPipe
):
41 """ FPConversion and De-norm
44 def __init__(self
, in_pspec
, out_pspec
, modkls
):
46 sc
= modkls(in_pspec
, out_pspec
)
48 super().__init
__(in_pspec
)
49 self
.out
= self
.ospec(None)
52 class FPCVTFtoIntBasePipe(ControlBase
):
53 def __init__(self
, modkls
, e_extra
, in_pspec
, out_pspec
):
54 ControlBase
.__init
__(self
)
55 self
.pipe1
= FPCVTConvertDeNorm(in_pspec
, out_pspec
, modkls
)
56 #self.pipe2 = FPNormToPack(out_pspec, e_extra=e_extra)
58 #self._eqs = self.connect([self.pipe1, self.pipe2])
59 self
._eqs
= self
.connect([self
.pipe1
, ])
61 def elaborate(self
, platform
):
62 m
= ControlBase
.elaborate(self
, platform
)
63 m
.submodules
.down
= self
.pipe1
64 #m.submodules.normpack = self.pipe2
69 class FPCVTBasePipe(ControlBase
):
70 def __init__(self
, modkls
, e_extra
, in_pspec
, out_pspec
):
71 ControlBase
.__init
__(self
)
72 self
.pipe1
= FPCVTConvertDeNorm(in_pspec
, out_pspec
, modkls
)
73 self
.pipe2
= FPNormToPack(out_pspec
, e_extra
=e_extra
)
75 self
._eqs
= self
.connect([self
.pipe1
, self
.pipe2
])
77 def elaborate(self
, platform
):
78 m
= ControlBase
.elaborate(self
, platform
)
79 m
.submodules
.down
= self
.pipe1
80 m
.submodules
.normpack
= self
.pipe2
85 class FPCVTMuxInOutBase(ReservationStations
):
86 """ Reservation-Station version of FPCVT pipeline.
88 * fan-in on inputs (an array of FPADDBaseData: a,b,mid)
89 * 2-stage multiplier pipeline
90 * fan-out on outputs (an array of FPPackData: z,mid)
92 Fan-in and Fan-out are combinatorial.
95 def __init__(self
, modkls
, e_extra
, in_width
, out_width
,
96 num_rows
, op_wid
=0, pkls
=FPCVTBasePipe
):
98 self
.id_wid
= num_bits(num_rows
)
100 self
.in_pspec
= PipelineSpec(in_width
, self
.id_wid
, self
.op_wid
)
101 self
.out_pspec
= PipelineSpec(out_width
, self
.id_wid
, op_wid
)
103 self
.alu
= pkls(modkls
, e_extra
, self
.in_pspec
, self
.out_pspec
)
104 ReservationStations
.__init
__(self
, num_rows
)
107 return FPADDBaseData(self
.in_pspec
)
110 return FPPackData(self
.out_pspec
)
113 def getkls(*args
, **kwargs
):
114 print ("getkls", args
, kwargs
)
115 return FPCVTMuxInOutBase(*args
, **kwargs
)
118 # factory which creates near-identical class structures that differ by
119 # the module and the e_extra argument. at some point it would be good
120 # to merge these into a single dynamic "thing" that takes an operator.
121 # however, the difference(s) in the bitwidths makes that a little less
123 muxfactoryinput
= [("FPCVTDownMuxInOut", FPCVTDownConvertMod
, True, ),
124 ("FPCVTUpMuxInOut", FPCVTUpConvertMod
, False, ),
125 ("FPCVTIntMuxInOut", FPCVTIntToFloatMod
, True, ),
128 for (name
, kls
, e_extra
) in muxfactoryinput
:
129 fn
= functools
.partial(getkls
, kls
, e_extra
)
130 setattr(sys
.modules
[__name__
], name
, fn
)
133 class FPCVTF2IntMuxInOut(FPCVTMuxInOutBase
):
134 """ Reservation-Station version of FPCVT pipeline.
136 * fan-in on inputs (an array of FPADDBaseData: a,b,mid)
137 * 2-stage multiplier pipeline
138 * fan-out on outputs (an array of FPPackData: z,mid)
140 Fan-in and Fan-out are combinatorial.
143 def __init__(self
, in_width
, out_width
, num_rows
, op_wid
=0):
144 FPCVTMuxInOutBase
.__init
__(self
, FPCVTFloatToIntMod
, False,
147 pkls
=FPCVTFtoIntBasePipe
)