a671f99d1ceb48f57af88286ccdc1ae2398b5ecf
[ieee754fpu.git] / src / ieee754 / fpdiv / mulAddRecFN.py
1 """
2 /*============================================================================
3
4 This Verilog source file is part of the Berkeley HardFloat IEEE Floating-Point
5 Arithmetic Package, Release 1, by John R. Hauser.
6
7 Copyright 2019 The Regents of the University of California. All rights
8 reserved.
9
10 Redistribution and use in source and binary forms, with or without
11 modification, are permitted provided that the following conditions are met:
12
13 1. Redistributions of source code must retain the above copyright notice,
14 this list of conditions, and the following disclaimer.
15
16 2. Redistributions in binary form must reproduce the above copyright notice,
17 this list of conditions, and the following disclaimer in the documentation
18 and/or other materials provided with the distribution.
19
20 3. Neither the name of the University nor the names of its contributors may
21 be used to endorse or promote products derived from this software without
22 specific prior written permission.
23
24 THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
25 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
27 DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
28 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35 =============================================================================*/
36
37 `include "HardFloat_consts.vi"
38 `include "HardFloat_specialize.vi"
39
40 """
41
42 from nmigen import Elaboratable, Cat, Const, Mux, Module, Signal
43 from nmutil.concurrentunit import num_bits
44
45 #/*----------------------------------------------------------------------------
46 #*----------------------------------------------------------------------------*/
47
48 class mulAddRecFNToRaw_preMul(Elaboratable):
49 def __init__(self, expWidth=3, sigWidth=3):
50 # inputs
51 self.control = Signal(floatControlWidth, reset_less=True)
52 self.op = Signal(2, reset_less=True)
53 self.a = Signal(expWidth + sigWidth + 1, reset_less=True)
54 self.b = Signal(expWidth + sigWidth + 1, reset_less=True)
55 self.c = Signal(expWidth + sigWidth + 1, reset_less=True)
56 self.roundingMode = Signal(3, reset_less=True)
57
58 # outputs
59 self.mulAddA = Signal(sigWidth, reset_less=True)
60 self.mulAddB = Signal(sigWidth, reset_less=True)
61 self.mulAddC = Signal(sigWidth*2, reset_less=True)
62 self.intermed_compactState = Signal(6, reset_less=True)
63 self.intermed_sExp = Signal(expWidth + 2, reset_less=True)
64 wid = num_bits(sigWidth + 1)
65 self.intermed_CDom_CAlignDist = Signal(wid, reset_less=True)
66 self.intermed_highAlignedSigC = Signal((sigWidth + 2), reset_less=True)
67
68 def elaborate(self, platform):
69 m = Module()
70 comb = m.d.comb
71
72 #/*-------------------------------------------------------------------
73 #*--------------------------------------------------------------------*/
74 prodWidth = sigWidth*2;
75 sigSumWidth = sigWidth + prodWidth + 3;
76 #/*-------------------------------------------------------------------
77 #*-------------------------------------------------------------------*/
78 isNaNA = Signal(reset_less=True)
79 isInfA = Signal(reset_less=True)
80 isZeroA = Signal(reset_less=True)
81 signA = Signal(reset_less=True)
82
83 sExpA = Signal((expWidth + 2, True), reset_less=True)
84 sigA = Signal(sigWidth+1, reset_less=True)
85 m.submodules.recFNToRawFN_a = rf = recFNToRawFN(expWidth, sigWidth)
86 comb += [(a, isNaNA, isInfA, isZeroA, signA, sExpA, sigA)]
87
88 isSigNaNA = Signal(reset_less=True)
89 m.submodules.isSigNaN_a = nan_a = isSigNaNRecFN(expWidth, sigWidth)
90 comb += [(a, isSigNaNA)]
91
92 isNaNB = Signal(reset_less=True)
93 isInfB = Signal(reset_less=True)
94 isZeroB = Signal(reset_less=True)
95 signB = Signal(reset_less=True)
96
97 sExpB = Signal((expWidth + 2, True), reset_less=True)
98 sigB = Signal(sigWidth+1, reset_less=True)
99 m.submodules.recFNToRawFN_b = rf = recFNToRawFN(expWidth, sigWidth)
100 comb += [(b, isNaNB, isInfB, isZeroB, signB, sExpB, sigB)]
101
102 isSigNaNB = Signal(reset_less=True)
103 m.submodules.isSigNaN_b = nan_b = isSigNaNRecFN(expWidth, sigWidth)
104 comb += [(b, isSigNaNB)]
105
106 isNaNC = Signal(reset_less=True)
107 isInfC = Signal(reset_less=True)
108 isZeroC = Signal(reset_less=True)
109 signC = Signal(reset_less=True)
110
111 sExpC = Signal((expWidth + 2, True), reset_less=True)
112 sigC = Signal(sigWidth+1, reset_less=True)
113 m.submodules.recFNToRawFN_c = rf = recFNToRawFN(expWidth, sigWidth)
114 comb += [(c, isNaNC, isInfC, isZeroC, signC, sExpC, sigC)]
115
116 isSigNaNC = Signal(reset_less=True)
117 m.submodules.isSigNaN_c = nan_c = isSigNaNRecFN(expWidth, sigWidth)
118 comb += [(c, isSigNaNC)]
119
120 #/*-------------------------------------------------------------------
121 #*-------------------------------------------------------------------*/
122 signProd = Signal(reset_less=True)
123 sExpAlignedProd = Signal((expWidth + 3, True), reset_less=True)
124 doSubMags = Signal(reset_less=True)
125 opSignC = Signal(reset_less=True)
126 roundingMode_min = Signal(reset_less=True)
127
128 comb += signProd.eq(signA ^ signB ^ op[1])
129 comb += sExpAlignedProd.eq(sExpA + sExpB + \
130 (-(1<<expWidth) + sigWidth + 3))
131 comb += doSubMags.eq(signProd ^ signC ^ op[0])
132 comb += opSignC.eq(signProd ^ doSubMags)
133 comb += roundingMode_min.eq(roundingMode == ROUND_MIN)
134
135 #/*-------------------------------------------------------------------
136 #*-------------------------------------------------------------------*/
137 sNatCAlignDist = Signal((expWidth + 3, True), reset_less=True)
138 posNatCAlignDist = Signal(expWidth + 2, reset_less=True)
139 isMinCAlign = Signal(reset_less=True)
140 CIsDominant = Signal(reset_less=True)
141 sExpSum = Signal((expWidth + 2, True), reset_less=True)
142 CAlignDist = Signal(num_bits(sigSumWidth), reset_less=True)
143 extComplSigC = Signal((sigSumWidth + 3, True), reset_less=True)
144 mainAlignedSigC = Signal(sigSumWidth + 2, reset_less=True)
145
146 CGrainAlign = (sigSumWidth - sigWidth - 1) & 3;
147 grainAlignedSigC = Signal(sigWidth+CGrainAlign + 1, reset_less=True)
148 reduced4SigC = Signal((sigWidth+CGrainAlign)/4 + 1, reset_less=True)
149 m.submodules.compressBy4_sigC = compressBy4(sigWidth + 1 + CGrainAlign)
150 comb += (grainAlignedSigC, reduced4SigC)
151 CExtraMaskHiBound = (sigSumWidth - 1)/4;
152 CExtraMaskLoBound = (sigSumWidth - sigWidth - 1)/4;
153 CExtraMask = Signal(CExtraMaskHiBound - CExtraMaskLoBound,
154 reset_less=True)
155 m.submodules.lowMask_CExtraMask = lowMaskHiLo(clog2(sigSumWidth) - 2,
156 CExtraMaskHiBound,
157 CExtraMaskLoBound))
158 comb += (CAlignDist[(clog2(sigSumWidth) - 1):2], CExtraMask);
159 reduced4CExtra = Signal(reset_less=True)
160 alignedSigC = Signal(sigSumWidth, reset_less=True)
161
162 comb += [
163 sNatCAlignDist.eq(sExpAlignedProd - sExpC),
164 posNatCAlignDist.eq(sNatCAlignDist[:expWidth + 2]),
165 isMinCAlign.eq(isZeroA | isZeroB | (sNatCAlignDist < 0))
166 CIsDominant.eq(~isZeroC & \
167 (isMinCAlign | (posNatCAlignDist <= sigWidth)))
168 sExpSum.eq(Mux(CIsDominant, sExpC, sExpAlignedProd - sigWidth)),
169 CAlignDist.eq(Mux(isMinCAlign, 0,
170 Mux((posNatCAlignDist < sigSumWidth - 1),
171 posNatCAlignDist[:num_bits(sigSumWidth)],
172 sigSumWidth - 1)),
173 # XXX check! {doSubMags ? ~sigC : sigC,
174 # {(sigSumWidth - sigWidth + 2){doSubMags}}};
175 sc = [doSubMags] * (sigSumWidth - sigWidth + 2) + \
176 [Mux(doSubMags, ~sigC, sigC)]
177 extComplSigC.eq(Cat(*sc))
178 # XXX check! nmigen doesn't have >>> operator, only >>
179 mainAlignedSigC.eq(extComplSigC >>> CAlignDist),
180 grainAlignedSigC.eq(sigC<<CGrainAlign),
181 compressBy4_sigC.in.eq(grainAlignedSigC),
182 reduced4SigC.eq(compressBy4_sigC.out),
183 lowMaskHiLo.in.eq(CAlignDist[2:(clog2(sigSumWidth)]),
184 CExtraMask.eq(lowMaskHiLo.out),
185 reduced4CExtra.eq((reduced4SigC & CExtraMask).bool()),
186 alignedSigC = Cat(
187 Mux(doSubMags, (mainAlignedSigC[:3]=0b111) & ~reduced4CExtra,
188 (mainAlignedSigC[:3].bool()) | reduced4CExtra),
189 mainAlignedSigC>>3)
190 ]
191 #/*-------------------------------------------------------------------
192 #*-------------------------------------------------------------------*/
193 isNaNAOrB = Signal(reset_less=True)
194 isNaNAny = Signal(reset_less=True)
195 isInfAOrB = Signal(reset_less=True)
196 invalidProd = Signal(reset_less=True)
197 notSigNaN_invalidExc = Signal(reset_less=True)
198 invalidExc = Signal(reset_less=True)
199 notNaN_addZeros = Signal(reset_less=True)
200 specialCase = Signal(reset_less=True)
201 specialNotNaN_signOut = Signal(reset_less=True)
202 comb += [
203 isNaNAOrB.eq(isNaNA | isNaNB),
204 isNaNAny.eq(isNaNAOrB | isNaNC),
205 isInfAOrB.eq(isInfA | isInfB),
206 invalidProd.eq((isInfA & isZeroB) | (isZeroA & isInfB)),
207 notSigNaN_invalidExc.eq(
208 invalidProd | (!isNaNAOrB & isInfAOrB & isInfC & doSubMags)),
209 invalidExc.eq(
210 isSigNaNA | isSigNaNB | isSigNaNC | notSigNaN_invalidExc),
211 notNaN_addZeros.eq((isZeroA | isZeroB) && isZeroC),
212 specialCase.eq(isNaNAny | isInfAOrB | isInfC | notNaN_addZeros),
213 specialNotNaN_signOut.eq(
214 (isInfAOrB & signProd) | (isInfC & opSignC)
215 | (notNaN_addZeros & !roundingMode_min & signProd & opSignC)
216 | (notNaN_addZeros & roundingMode_min & (signProd | opSignC)))
217 ]
218
219 special_signOut = specialNotNaN_signOut;
220 #/*-------------------------------------------------------------------
221 # *-------------------------------------------------------------------*/
222 mulAddA = sigA;
223 mulAddB = sigB;
224 mulAddC = Signal(prodWidth, reset_less=True)
225 intermed_compactState = Signal(6, reset_less=True)
226
227 comb += mulAddC.eq(alignedSigC[1:prodWidth+1])
228 comb += intermed_compactState.eq(Cat(
229 special_signOut,
230 notNaN_addZeros | (~specialCase & alignedSigC[0]),
231 isInfAOrB | isInfC | (~specialCase & CIsDominant ),
232 isNaNAny | (~specialCase & doSubMags ),
233 invalidExc | (~specialCase & signProd ),
234 specialCase,))
235 intermed_sExp = sExpSum;
236 intermed_CDom_CAlignDist = CAlignDist[(clog2(sigWidth + 1) - 1):0];
237 intermed_highAlignedSigC =
238 alignedSigC[(sigSumWidth - 1):(prodWidth + 1)];
239
240 return m
241
242 #/*------------------------------------------------------------------------
243 #*------------------------------------------------------------------------*/
244
245 class mulAddRecFNToRaw_postMul(Elaboratable):
246
247 def __init__(self, expWidth = 3, parameter sigWidth = 3):
248 # inputs
249 self.control = Signal(floatControlWidth, reset_less=True)
250 self.op = Signal(2, reset_less=True)
251 self.a = Signal(expWidth + sigWidth + 1, reset_less=True)
252 self.b = Signal(expWidth + sigWidth + 1, reset_less=True)
253 self.c = Signal(expWidth + sigWidth + 1, reset_less=True)
254 self.roundingMode = Signal(3, reset_less=True)
255
256 # outputs
257 self.mulAddA = Signal(sigWidth, reset_less=True)
258 self.mulAddB = Signal(sigWidth, reset_less=True)
259 self.mulAddC = Signal(sigWidth*2, reset_less=True)
260
261 # inputs
262 self.intermed_compactState = Signal(6, reset_less=True)
263 self.intermed_sExp = Signal(expWidth + 2, reset_less=True)
264 wid = num_bits(sigWidth + 1)
265 self.intermed_CDom_CAlignDist = Signal(wid, reset_less=True)
266 self.intermed_highAlignedSigC = Signal((sigWidth + 2), reset_less=True)
267 self.mulAddResult = Signal(sigWidth*2, reset_less=True)
268 self.roundingMode = Signal(3, reset_less=True)
269
270 # outputs
271 self.invalidExc = Signal(reset_less=True)
272 self.out_isNaN = Signal(reset_less=True)
273 self.out_isInf = Signal(reset_less=True)
274 self.out_isZero = Signal(reset_less=True)
275 self.out_sign = Signal(reset_less=True)
276 self.out_sExp = Signal((expWidth + 2, True), reset_less=True)
277 self.out_sig = Signal(sigWidth + 3, reset_less=True)
278
279 def elaborate(self, platform):
280 m = Module()
281 comb = m.d.comb
282
283 #/*-------------------------------------------------------------------
284 #*-------------------------------------------------------------------*/
285 prodWidth = sigWidth*2;
286 sigSumWidth = sigWidth + prodWidth + 3;
287
288 #/*-------------------------------------------------------------------
289 #*-------------------------------------------------------------------*/
290 wire specialCase = Signal(reset_less=True)
291 assign invalidExc = Signal(reset_less=True)
292 assign out_isNaN = Signal(reset_less=True)
293 assign out_isInf = Signal(reset_less=True)
294 wire notNaN_addZeros = Signal(reset_less=True)
295 wire signProd = Signal(reset_less=True)
296 wire doSubMags = Signal(reset_less=True)
297 wire CIsDominant = Signal(reset_less=True)
298 wire bit0AlignedSigC = Signal(reset_less=True)
299 wire special_signOut = Signal(reset_less=True)
300 comb += [
301 specialCase .eq( intermed_compactState[5] ),
302 invalidExc .eq( specialCase & intermed_compactState[4] ),
303 out_isNaN .eq( specialCase & intermed_compactState[3] ),
304 out_isInf .eq( specialCase & intermed_compactState[2] ),
305 notNaN_addZeros .eq( specialCase & intermed_compactState[1] ),
306 signProd .eq( intermed_compactState[4] ),
307 doSubMags .eq( intermed_compactState[3] ),
308 CIsDominant .eq( intermed_compactState[2] ),
309 bit0AlignedSigC .eq( intermed_compactState[1] ),
310 special_signOut .eq( intermed_compactState[0] ),
311 ]
312
313 #/*-------------------------------------------------------------------
314 #*-------------------------------------------------------------------*/
315 opSignC = Signal(reset_less=True)
316 incHighAlignedSigC = Signal(sigWidth + 3, reset_less=True)
317 sigSum = Signal(sigSumWidth, reset_less=True)
318 roundingMode_min = Signal(reset_less=True)
319
320 comb += [\
321 opSignC.eq(signProd ^ doSubMags),
322 incHighAlignedSigC.eq(intermed_highAlignedSigC + 1),
323 sigSum.eq(Cat(bit0AlignedSigC,
324 mulAddResult[(prodWidth - 1):0],
325 Mux(mulAddResult[prodWidth],
326 incHighAlignedSigC,
327 intermed_highAlignedSigC))),
328 roundingMode_min.eq(roundingMode == `round_min),
329 ]
330
331 #/*-------------------------------------------------------------------
332 #*-------------------------------------------------------------------*/
333 CDom_sign = Signal(reset_less=True)
334 CDom_sExp = Signal((expWidth + 2, True), reset_less=True)
335 CDom_absSigSum = Signal(prodWidth+2, reset_less=True)
336 CDom_absSigSumExtra = Signal(reset_less=True)
337 CDom_mainSig = Signal(sigWidth+5, reset_less=True)
338 CDom_grainAlignedLowSig = Signal(sigWidth | 3, reset_less=True)
339 CDom_reduced4LowSig = Signal(sigWidth/4+1, reset_less=True)
340 CDom_sigExtraMask = Signal(sigWidth/4, reset_less=True)
341
342 lowMask_CDom_sigExtraMask = lm
343 m.submodules.lm = lm = lowMaskLoHi(clog2(sigWidth + 1) - 2, 0,
344 sigWidth/4)
345 CDom_reduced4SigExtra = Signal(reset_less=True)
346 CDom_sig = Signal(sigWidth+3, reset_less=True)
347
348 comb += [\
349 CDom_sign.eq(opSignC),
350 CDom_sExp.eq(intermed_sExp - doSubMags),
351 CDom_absSigSum.eq(Mux(doSubMags,
352 ~sigSum[sigWidth+1:sigSumWidth],
353 Cat(sigSum[sigWidth+2 : sigSumWidth - 2],
354 intermed_highAlignedSigC[(sigWidth + 1):sigWidth],
355 0b0)),
356 CDom_absSigSumExtra.eq(Mux(doSubMags,
357 (~sigSum[1:sigWidth+1]).bool(),
358 sigSum[1:sigWidth + 2].bool())),
359 CDom_mainSig.eq(
360 (CDom_absSigSum<<intermed_CDom_CAlignDist)>>(sigWidth - 3)),
361 CDom_grainAlignedLowSig.eq(
362 CDom_absSigSum[(sigWidth - 1):0]<<(~sigWidth & 3)),
363 CDom_reduced4LowSig.eq(compressBy4_CDom_absSigSum.out),
364 compressBy4_CDom_absSigSum.in.eq(CDom_grainAlignedLowSig),
365 lowMask_CDom_sigExtraMask.in.eq(
366 intermed_CDom_CAlignDist[2:clog2(sigWidth + 1)]),
367 CDom_sigExtraMask.eq(lowMask_CDom_sigExtraMask.out),
368 CDom_reduced4SigExtra.eq(
369 (CDom_reduced4LowSig & CDom_sigExtraMask).bool()),
370 CDom_sig.eq(Cat((CDom_mainSig[:3]).bool() |
371 CDom_reduced4SigExtra |
372 CDom_absSigSumExtra,
373 CDom_mainSig>>3)),
374 ]
375
376 #/*-------------------------------------------------------------------
377 #*-------------------------------------------------------------------*/
378 wire notCDom_signSigSum = sigSum[prodWidth + 3];
379 wire [(prodWidth + 2):0] notCDom_absSigSum =
380 notCDom_signSigSum ? ~sigSum[(prodWidth + 2):0]
381 : sigSum[(prodWidth + 2):0] + doSubMags;
382 wire [(prodWidth + 2)/2:0] notCDom_reduced2AbsSigSum;
383 compressBy2#(prodWidth + 3)
384 compressBy2_notCDom_absSigSum(
385 notCDom_absSigSum, notCDom_reduced2AbsSigSum);
386 wire [(clog2(prodWidth + 4) - 2):0] notCDom_normDistReduced2;
387 countLeadingZeros#((prodWidth + 2)/2 + 1, clog2(prodWidth + 4) - 1)
388 countLeadingZeros_notCDom(
389 notCDom_reduced2AbsSigSum, notCDom_normDistReduced2);
390 wire [(clog2(prodWidth + 4) - 1):0] notCDom_nearNormDist =
391 notCDom_normDistReduced2<<1;
392 wire signed [(expWidth + 1):0] notCDom_sExp =
393 intermed_sExp - notCDom_nearNormDist;
394 wire [(sigWidth + 4):0] notCDom_mainSig =
395 ({0b0, notCDom_absSigSum}<<notCDom_nearNormDist)>>(sigWidth - 1);
396 wire [(((sigWidth/2 + 1) | 1) - 1):0] CDom_grainAlignedLowReduced2Sig =
397 notCDom_reduced2AbsSigSum[sigWidth/2:0]<<((sigWidth/2) & 1);
398 wire [(sigWidth + 2)/4:0] notCDom_reduced4AbsSigSum;
399 compressBy2#((sigWidth/2 + 1) | 1)
400 compressBy2_notCDom_reduced2AbsSigSum(
401 CDom_grainAlignedLowReduced2Sig, notCDom_reduced4AbsSigSum);
402 wire [((sigWidth + 2)/4 - 1):0] notCDom_sigExtraMask;
403 lowMaskLoHi#(clog2(prodWidth + 4) - 2, 0, (sigWidth + 2)/4)
404 lowMask_notCDom_sigExtraMask(
405 notCDom_normDistReduced2[(clog2(prodWidth + 4) - 2):1],
406 notCDom_sigExtraMask
407 );
408 wire notCDom_reduced4SigExtra =
409 |(notCDom_reduced4AbsSigSum & notCDom_sigExtraMask);
410 wire [(sigWidth + 2):0] notCDom_sig =
411 {notCDom_mainSig>>3,
412 (|notCDom_mainSig[2:0]) | notCDom_reduced4SigExtra};
413 wire notCDom_completeCancellation =
414 (notCDom_sig[(sigWidth + 2):(sigWidth + 1)] == 0);
415 wire notCDom_sign =
416 notCDom_completeCancellation ? roundingMode_min
417 : signProd ^ notCDom_signSigSum;
418 #/*-------------------------------------------------------------------
419 #*-------------------------------------------------------------------*/
420 assign out_isZero =
421 notNaN_addZeros | (!CIsDominant && notCDom_completeCancellation);
422 assign out_sign =
423 ( specialCase && special_signOut)
424 | (!specialCase && CIsDominant && CDom_sign )
425 | (!specialCase && !CIsDominant && notCDom_sign );
426 assign out_sExp = CIsDominant ? CDom_sExp : notCDom_sExp;
427 assign out_sig = CIsDominant ? CDom_sig : notCDom_sig;
428
429 /*----------------------------------------------------------------------------
430 *----------------------------------------------------------------------------*/
431
432 module
433 mulAddRecFNToRaw#(parameter expWidth = 3, parameter sigWidth = 3) (
434 input [(`floatControlWidth - 1):0] control,
435 input [1:0] op,
436 input [(expWidth + sigWidth):0] a,
437 input [(expWidth + sigWidth):0] b,
438 input [(expWidth + sigWidth):0] c,
439 input [2:0] roundingMode,
440 output invalidExc,
441 output out_isNaN,
442 output out_isInf,
443 output out_isZero,
444 output out_sign,
445 output signed [(expWidth + 1):0] out_sExp,
446 output [(sigWidth + 2):0] out_sig
447 );
448 `include "HardFloat_localFuncs.vi"
449
450 wire [(sigWidth - 1):0] mulAddA, mulAddB;
451 wire [(sigWidth*2 - 1):0] mulAddC;
452 wire [5:0] intermed_compactState;
453 wire signed [(expWidth + 1):0] intermed_sExp;
454 wire [(clog2(sigWidth + 1) - 1):0] intermed_CDom_CAlignDist;
455 wire [(sigWidth + 1):0] intermed_highAlignedSigC;
456 mulAddRecFNToRaw_preMul#(expWidth, sigWidth)
457 mulAddToRaw_preMul(
458 control,
459 op,
460 a,
461 b,
462 c,
463 roundingMode,
464 mulAddA,
465 mulAddB,
466 mulAddC,
467 intermed_compactState,
468 intermed_sExp,
469 intermed_CDom_CAlignDist,
470 intermed_highAlignedSigC
471 );
472 wire [sigWidth*2:0] mulAddResult = mulAddA * mulAddB + mulAddC;
473 mulAddRecFNToRaw_postMul#(expWidth, sigWidth)
474 mulAddToRaw_postMul(
475 intermed_compactState,
476 intermed_sExp,
477 intermed_CDom_CAlignDist,
478 intermed_highAlignedSigC,
479 mulAddResult,
480 roundingMode,
481 invalidExc,
482 out_isNaN,
483 out_isInf,
484 out_isZero,
485 out_sign,
486 out_sExp,
487 out_sig
488 );
489
490 endmodule
491
492 /*----------------------------------------------------------------------------
493 *----------------------------------------------------------------------------*/
494
495 module
496 mulAddRecFN#(parameter expWidth = 3, parameter sigWidth = 3) (
497 input [(`floatControlWidth - 1):0] control,
498 input [1:0] op,
499 input [(expWidth + sigWidth):0] a,
500 input [(expWidth + sigWidth):0] b,
501 input [(expWidth + sigWidth):0] c,
502 input [2:0] roundingMode,
503 output [(expWidth + sigWidth):0] out,
504 output [4:0] exceptionFlags
505 );
506
507 wire invalidExc, out_isNaN, out_isInf, out_isZero, out_sign;
508 wire signed [(expWidth + 1):0] out_sExp;
509 wire [(sigWidth + 2):0] out_sig;
510 mulAddRecFNToRaw#(expWidth, sigWidth)
511 mulAddRecFNToRaw(
512 control,
513 op,
514 a,
515 b,
516 c,
517 roundingMode,
518 invalidExc,
519 out_isNaN,
520 out_isInf,
521 out_isZero,
522 out_sign,
523 out_sExp,
524 out_sig
525 );
526 roundRawFNToRecFN#(expWidth, sigWidth, 0)
527 roundRawOut(
528 control,
529 invalidExc,
530 1'b0,
531 out_isNaN,
532 out_isInf,
533 out_isZero,
534 out_sign,
535 out_sExp,
536 out_sig,
537 roundingMode,
538 out,
539 exceptionFlags
540 );
541
542 endmodule
543