d8f0db06cb6124045b0b070f7f2e7af03b3f15e5
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 nmutil
.singlepipe
import SimpleHandshake
, StageChain
26 from ieee754
.fpcommon
.fpbase
import FPState
27 from ieee754
.pipeline
import PipelineSpec
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(FPState
, SimpleHandshake
):
44 """ FPConversion and De-norm
47 def __init__(self
, modkls
, in_pspec
, out_pspec
):
48 FPState
.__init
__(self
, "cvt")
49 sc
= modkls(in_pspec
, out_pspec
)
50 SimpleHandshake
.__init
__(self
, sc
)
51 self
.out
= self
.ospec(None)
54 class FPCVTFtoIntBasePipe(ControlBase
):
55 def __init__(self
, modkls
, e_extra
, in_pspec
, out_pspec
):
56 ControlBase
.__init
__(self
)
57 self
.pipe1
= FPCVTConvertDeNorm(modkls
, in_pspec
, out_pspec
)
58 #self.pipe2 = FPNormToPack(out_pspec, e_extra=e_extra)
60 #self._eqs = self.connect([self.pipe1, self.pipe2])
61 self
._eqs
= self
.connect([self
.pipe1
, ])
63 def elaborate(self
, platform
):
64 m
= ControlBase
.elaborate(self
, platform
)
65 m
.submodules
.down
= self
.pipe1
66 #m.submodules.normpack = self.pipe2
71 class FPCVTBasePipe(ControlBase
):
72 def __init__(self
, modkls
, e_extra
, in_pspec
, out_pspec
):
73 ControlBase
.__init
__(self
)
74 self
.pipe1
= FPCVTConvertDeNorm(modkls
, in_pspec
, out_pspec
)
75 self
.pipe2
= FPNormToPack(out_pspec
, e_extra
=e_extra
)
77 self
._eqs
= self
.connect([self
.pipe1
, self
.pipe2
])
79 def elaborate(self
, platform
):
80 m
= ControlBase
.elaborate(self
, platform
)
81 m
.submodules
.down
= self
.pipe1
82 m
.submodules
.normpack
= self
.pipe2
87 class FPCVTMuxInOutBase(ReservationStations
):
88 """ Reservation-Station version of FPCVT pipeline.
90 * fan-in on inputs (an array of FPADDBaseData: a,b,mid)
91 * 2-stage multiplier pipeline
92 * fan-out on outputs (an array of FPPackData: z,mid)
94 Fan-in and Fan-out are combinatorial.
97 def __init__(self
, modkls
, e_extra
, in_width
, out_width
,
98 num_rows
, op_wid
=0, pkls
=FPCVTBasePipe
):
100 self
.id_wid
= num_bits(num_rows
)
102 self
.in_pspec
= PipelineSpec(in_width
, id_wid
, self
.op_wid
)
103 self
.out_pspec
= PipelineSpec(out_width
, id_wid
, op_wid
)
105 self
.alu
= pkls(modkls
, e_extra
, self
.in_pspec
, self
.out_pspec
)
106 ReservationStations
.__init
__(self
, num_rows
)
109 return FPADDBaseData(self
.in_pspec
)
112 return FPPackData(self
.out_pspec
)
115 def getkls(*args
, **kwargs
):
116 print ("getkls", args
, kwargs
)
117 return FPCVTMuxInOutBase(*args
, **kwargs
)
120 # factory which creates near-identical class structures that differ by
121 # the module and the e_extra argument. at some point it would be good
122 # to merge these into a single dynamic "thing" that takes an operator.
123 # however, the difference(s) in the bitwidths makes that a little less
125 muxfactoryinput
= [("FPCVTDownMuxInOut", FPCVTDownConvertMod
, True, ),
126 ("FPCVTUpMuxInOut", FPCVTUpConvertMod
, False, ),
127 ("FPCVTIntMuxInOut", FPCVTIntToFloatMod
, True, ),
130 for (name
, kls
, e_extra
) in muxfactoryinput
:
131 fn
= functools
.partial(getkls
, kls
, e_extra
)
132 setattr(sys
.modules
[__name__
], name
, fn
)
135 class FPCVTF2IntMuxInOut(FPCVTMuxInOutBase
):
136 """ Reservation-Station version of FPCVT pipeline.
138 * fan-in on inputs (an array of FPADDBaseData: a,b,mid)
139 * 2-stage multiplier pipeline
140 * fan-out on outputs (an array of FPPackData: z,mid)
142 Fan-in and Fan-out are combinatorial.
145 def __init__(self
, in_width
, out_width
, num_rows
, op_wid
=0):
146 FPCVTMuxInOutBase
.__init
__(self
, FPCVTFloatToIntMod
, False,
149 pkls
=FPCVTFtoIntBasePipe
)