605bb16a65aa564560b9fae0acd66743da489e10
1 """IEEE754 Floating Point Conversion
3 Copyright (C) 2019 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
11 from nmigen
import Module
, Signal
, Cat
, Const
, Mux
, Elaboratable
12 from nmigen
.cli
import main
, verilog
14 from nmutil
.singlepipe
import ControlBase
15 from nmutil
.concurrentunit
import ReservationStations
, num_bits
17 from ieee754
.fpcommon
.getop
import FPADDBaseData
18 from ieee754
.fpcommon
.pack
import FPPackData
19 from ieee754
.fpcommon
.normtopack
import FPNormToPack
22 from nmigen
import Module
, Signal
, Elaboratable
25 from ieee754
.fpcommon
.getop
import FPPipeContext
27 from ieee754
.pipeline
import PipelineSpec
, DynamicPipe
29 from ieee754
.fcvt
.float2int
import FPCVTFloatToIntMod
30 from ieee754
.fcvt
.int2float
import FPCVTIntToFloatMod
31 from ieee754
.fcvt
.upsize
import FPCVTUpConvertMod
32 from ieee754
.fcvt
.downsize
import FPCVTDownConvertMod
37 self
.signed
= Signal(reset_less
=True)
40 return [self
.signed
.eq(i
)]
43 class FPCVTConvertDeNorm(DynamicPipe
):
44 """ FPConversion and De-norm
47 def __init__(self
, in_pspec
, out_pspec
, modkls
):
49 sc
= modkls(in_pspec
, out_pspec
)
51 super().__init
__(in_pspec
)
52 self
.out
= self
.ospec(None)
55 class FPCVTFtoIntBasePipe(ControlBase
):
56 def __init__(self
, modkls
, e_extra
, in_pspec
, out_pspec
):
57 ControlBase
.__init
__(self
)
58 self
.pipe1
= FPCVTConvertDeNorm(in_pspec
, out_pspec
, modkls
)
59 #self.pipe2 = FPNormToPack(out_pspec, e_extra=e_extra)
61 #self._eqs = self.connect([self.pipe1, self.pipe2])
62 self
._eqs
= self
.connect([self
.pipe1
, ])
64 def elaborate(self
, platform
):
65 m
= ControlBase
.elaborate(self
, platform
)
66 m
.submodules
.down
= self
.pipe1
67 #m.submodules.normpack = self.pipe2
72 class FPCVTBasePipe(ControlBase
):
73 def __init__(self
, modkls
, e_extra
, in_pspec
, out_pspec
):
74 ControlBase
.__init
__(self
)
75 self
.pipe1
= FPCVTConvertDeNorm(in_pspec
, out_pspec
, modkls
)
76 self
.pipe2
= FPNormToPack(out_pspec
, e_extra
=e_extra
)
78 self
._eqs
= self
.connect([self
.pipe1
, self
.pipe2
])
80 def elaborate(self
, platform
):
81 m
= ControlBase
.elaborate(self
, platform
)
82 m
.submodules
.down
= self
.pipe1
83 m
.submodules
.normpack
= self
.pipe2
88 class FPCVTMuxInOutBase(ReservationStations
):
89 """ Reservation-Station version of FPCVT pipeline.
91 * fan-in on inputs (an array of FPADDBaseData: a,b,mid)
92 * 2-stage multiplier pipeline
93 * fan-out on outputs (an array of FPPackData: z,mid)
95 Fan-in and Fan-out are combinatorial.
98 def __init__(self
, modkls
, e_extra
, in_width
, out_width
,
99 num_rows
, op_wid
=0, pkls
=FPCVTBasePipe
):
101 self
.id_wid
= num_bits(num_rows
)
103 self
.in_pspec
= PipelineSpec(in_width
, self
.id_wid
, self
.op_wid
)
104 self
.out_pspec
= PipelineSpec(out_width
, self
.id_wid
, op_wid
)
106 self
.alu
= pkls(modkls
, e_extra
, self
.in_pspec
, self
.out_pspec
)
107 ReservationStations
.__init
__(self
, num_rows
)
110 return FPADDBaseData(self
.in_pspec
)
113 return FPPackData(self
.out_pspec
)
116 class FPCVTF2IntMuxInOut(FPCVTMuxInOutBase
):
117 """ Reservation-Station version of FPCVT pipeline.
119 * fan-in on inputs (an array of FPADDBaseData: a,b,mid)
120 * 2-stage multiplier pipeline
121 * fan-out on outputs (an array of FPPackData: z,mid)
123 Fan-in and Fan-out are combinatorial.
126 def __init__(self
, in_width
, out_width
, num_rows
, op_wid
=0):
127 FPCVTMuxInOutBase
.__init
__(self
, FPCVTFloatToIntMod
, False,
130 pkls
=FPCVTFtoIntBasePipe
)
133 # factory which creates near-identical class structures that differ by
134 # the module and the e_extra argument. at some point it would be good
135 # to merge these into a single dynamic "thing" that takes an operator.
136 # however, the difference(s) in the bitwidths makes that a little less
138 muxfactoryinput
= [("FPCVTDownMuxInOut", FPCVTDownConvertMod
, True, ),
139 ("FPCVTUpMuxInOut", FPCVTUpConvertMod
, False, ),
140 ("FPCVTIntMuxInOut", FPCVTIntToFloatMod
, True, ),
143 def getkls(*args
, **kwargs
):
144 print ("getkls", args
, kwargs
)
145 return FPCVTMuxInOutBase(*args
, **kwargs
)
147 for (name
, kls
, e_extra
) in muxfactoryinput
:
148 fn
= functools
.partial(getkls
, kls
, e_extra
)
149 setattr(sys
.modules
[__name__
], name
, fn
)