start converting hardfloat-verilog fmac to nmigen
[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 extComplSigC.eq(Cat((sigSumWidth - sigWidth + 2){doSubMags}},
176 Mux(doSubMags, ~sigC, sigC))),
177 # XXX check! nmigen doesn't have >>> operator, only >>
178 mainAlignedSigC.eq(extComplSigC >>> CAlignDist),
179 grainAlignedSigC.eq(sigC<<CGrainAlign),
180 compressBy4_sigC.in.eq(grainAlignedSigC),
181 reduced4SigC.eq(compressBy4_sigC.out),
182 lowMaskHiLo.in.eq(CAlignDist[2:(clog2(sigSumWidth)]),
183 CExtraMask.eq(lowMaskHiLo.out),
184 reduced4CExtra.eq((reduced4SigC & CExtraMask).bool()),
185 alignedSigC = Cat(
186 Mux(doSubMags, (mainAlignedSigC[:3]=0b111) & ~reduced4CExtra,
187 (mainAlignedSigC[:3].bool()) | reduced4CExtra),
188 mainAlignedSigC>>3)
189 ]
190 #/*-------------------------------------------------------------------
191 #*-------------------------------------------------------------------*/
192 isNaNAOrB = Signal(reset_less=True)
193 isNaNAny = Signal(reset_less=True)
194 isInfAOrB = Signal(reset_less=True)
195 invalidProd = Signal(reset_less=True)
196 notSigNaN_invalidExc = Signal(reset_less=True)
197 invalidExc = Signal(reset_less=True)
198 notNaN_addZeros = Signal(reset_less=True)
199 specialCase = Signal(reset_less=True)
200 specialNotNaN_signOut = Signal(reset_less=True)
201 comb += [
202 isNaNAOrB.eq(isNaNA | isNaNB),
203 isNaNAny.eq(isNaNAOrB | isNaNC),
204 isInfAOrB.eq(isInfA | isInfB),
205 invalidProd.eq((isInfA & isZeroB) | (isZeroA & isInfB)),
206 notSigNaN_invalidExc.eq(
207 invalidProd | (!isNaNAOrB & isInfAOrB & isInfC & doSubMags)),
208 invalidExc.eq(
209 isSigNaNA | isSigNaNB | isSigNaNC | notSigNaN_invalidExc),
210 notNaN_addZeros.eq((isZeroA | isZeroB) && isZeroC),
211 specialCase.eq(isNaNAny | isInfAOrB | isInfC | notNaN_addZeros),
212 specialNotNaN_signOut.eq(
213 (isInfAOrB & signProd) | (isInfC & opSignC)
214 | (notNaN_addZeros & !roundingMode_min & signProd & opSignC)
215 | (notNaN_addZeros & roundingMode_min & (signProd | opSignC)))
216 ]
217
218 special_signOut = specialNotNaN_signOut;
219 #/*-------------------------------------------------------------------
220 # *-------------------------------------------------------------------*/
221 mulAddA = sigA;
222 mulAddB = sigB;
223 mulAddC = Signal(prodWidth, reset_less=True)
224 intermed_compactState = Signal(6, reset_less=True)
225
226 comb += mulAddC.eq(alignedSigC[1:prodWidth+1])
227 comb += intermed_compactState.eq(Cat(
228 special_signOut,
229 notNaN_addZeros | (~specialCase & alignedSigC[0]),
230 isInfAOrB | isInfC | (~specialCase & CIsDominant ),
231 isNaNAny | (~specialCase & doSubMags ),
232 invalidExc | (~specialCase & signProd ),
233 specialCase,))
234 intermed_sExp = sExpSum;
235 intermed_CDom_CAlignDist = CAlignDist[(clog2(sigWidth + 1) - 1):0];
236 intermed_highAlignedSigC =
237 alignedSigC[(sigSumWidth - 1):(prodWidth + 1)];
238
239 return m
240
241 #/*------------------------------------------------------------------------
242 #*------------------------------------------------------------------------*/
243
244 module
245 mulAddRecFNToRaw_postMul#(parameter expWidth = 3, parameter sigWidth = 3) (
246 intermed_compactState,
247 intermed_sExp,
248 intermed_CDom_CAlignDist,
249 intermed_highAlignedSigC,
250 mulAddResult,
251 roundingMode,
252 invalidExc,
253 out_isNaN,
254 out_isInf,
255 out_isZero,
256 out_sign,
257 out_sExp,
258 out_sig
259 );
260 `include "HardFloat_localFuncs.vi"
261 input [5:0] intermed_compactState;
262 input signed [(expWidth + 1):0] intermed_sExp;
263 input [(clog2(sigWidth + 1) - 1):0] intermed_CDom_CAlignDist;
264 input [(sigWidth + 1):0] intermed_highAlignedSigC;
265 input [sigWidth*2:0] mulAddResult;
266 input [2:0] roundingMode;
267 output invalidExc;
268 output out_isNaN;
269 output out_isInf;
270 output out_isZero;
271 output out_sign;
272 output signed [(expWidth + 1):0] out_sExp;
273 output [(sigWidth + 2):0] out_sig;
274
275 /*------------------------------------------------------------------------
276 *------------------------------------------------------------------------*/
277 localparam prodWidth = sigWidth*2;
278 localparam sigSumWidth = sigWidth + prodWidth + 3;
279 /*------------------------------------------------------------------------
280 *------------------------------------------------------------------------*/
281 wire specialCase = intermed_compactState[5];
282 assign invalidExc = specialCase && intermed_compactState[4];
283 assign out_isNaN = specialCase && intermed_compactState[3];
284 assign out_isInf = specialCase && intermed_compactState[2];
285 wire notNaN_addZeros = specialCase && intermed_compactState[1];
286 wire signProd = intermed_compactState[4];
287 wire doSubMags = intermed_compactState[3];
288 wire CIsDominant = intermed_compactState[2];
289 wire bit0AlignedSigC = intermed_compactState[1];
290 wire special_signOut = intermed_compactState[0];
291 `ifdef HardFloat_propagateNaNPayloads
292 wire [(sigWidth - 2):0] fractNaN = intermed_highAlignedSigC;
293 `endif
294 /*------------------------------------------------------------------------
295 *------------------------------------------------------------------------*/
296 wire opSignC = signProd ^ doSubMags;
297 wire [(sigWidth + 1):0] incHighAlignedSigC = intermed_highAlignedSigC + 1;
298 wire [(sigSumWidth - 1):0] sigSum =
299 {mulAddResult[prodWidth] ? incHighAlignedSigC
300 : intermed_highAlignedSigC,
301 mulAddResult[(prodWidth - 1):0],
302 bit0AlignedSigC};
303 wire roundingMode_min = (roundingMode == `round_min);
304 /*------------------------------------------------------------------------
305 *------------------------------------------------------------------------*/
306 wire CDom_sign = opSignC;
307 wire signed [(expWidth + 1):0] CDom_sExp = intermed_sExp - doSubMags;
308 wire [(sigWidth*2 + 1):0] CDom_absSigSum =
309 doSubMags ? ~sigSum[(sigSumWidth - 1):(sigWidth + 1)]
310 : {0b0, intermed_highAlignedSigC[(sigWidth + 1):sigWidth],
311 sigSum[(sigSumWidth - 3):(sigWidth + 2)]};
312 wire CDom_absSigSumExtra =
313 doSubMags ? !(&sigSum[sigWidth:1]) : |sigSum[(sigWidth + 1):1];
314 wire [(sigWidth + 4):0] CDom_mainSig =
315 (CDom_absSigSum<<intermed_CDom_CAlignDist)>>(sigWidth - 3);
316 wire [((sigWidth | 3) - 1):0] CDom_grainAlignedLowSig =
317 CDom_absSigSum[(sigWidth - 1):0]<<(~sigWidth & 3);
318 wire [sigWidth/4:0] CDom_reduced4LowSig;
319 compressBy4#(sigWidth | 3)
320 compressBy4_CDom_absSigSum(
321 CDom_grainAlignedLowSig, CDom_reduced4LowSig);
322 wire [(sigWidth/4 - 1):0] CDom_sigExtraMask;
323 lowMaskLoHi#(clog2(sigWidth + 1) - 2, 0, sigWidth/4)
324 lowMask_CDom_sigExtraMask(
325 intermed_CDom_CAlignDist[(clog2(sigWidth + 1) - 1):2],
326 CDom_sigExtraMask
327 );
328 wire CDom_reduced4SigExtra = |(CDom_reduced4LowSig & CDom_sigExtraMask);
329 wire [(sigWidth + 2):0] CDom_sig =
330 {CDom_mainSig>>3,
331 (|CDom_mainSig[2:0]) | CDom_reduced4SigExtra | CDom_absSigSumExtra};
332 /*------------------------------------------------------------------------
333 *------------------------------------------------------------------------*/
334 wire notCDom_signSigSum = sigSum[prodWidth + 3];
335 wire [(prodWidth + 2):0] notCDom_absSigSum =
336 notCDom_signSigSum ? ~sigSum[(prodWidth + 2):0]
337 : sigSum[(prodWidth + 2):0] + doSubMags;
338 wire [(prodWidth + 2)/2:0] notCDom_reduced2AbsSigSum;
339 compressBy2#(prodWidth + 3)
340 compressBy2_notCDom_absSigSum(
341 notCDom_absSigSum, notCDom_reduced2AbsSigSum);
342 wire [(clog2(prodWidth + 4) - 2):0] notCDom_normDistReduced2;
343 countLeadingZeros#((prodWidth + 2)/2 + 1, clog2(prodWidth + 4) - 1)
344 countLeadingZeros_notCDom(
345 notCDom_reduced2AbsSigSum, notCDom_normDistReduced2);
346 wire [(clog2(prodWidth + 4) - 1):0] notCDom_nearNormDist =
347 notCDom_normDistReduced2<<1;
348 wire signed [(expWidth + 1):0] notCDom_sExp =
349 intermed_sExp - notCDom_nearNormDist;
350 wire [(sigWidth + 4):0] notCDom_mainSig =
351 ({0b0, notCDom_absSigSum}<<notCDom_nearNormDist)>>(sigWidth - 1);
352 wire [(((sigWidth/2 + 1) | 1) - 1):0] CDom_grainAlignedLowReduced2Sig =
353 notCDom_reduced2AbsSigSum[sigWidth/2:0]<<((sigWidth/2) & 1);
354 wire [(sigWidth + 2)/4:0] notCDom_reduced4AbsSigSum;
355 compressBy2#((sigWidth/2 + 1) | 1)
356 compressBy2_notCDom_reduced2AbsSigSum(
357 CDom_grainAlignedLowReduced2Sig, notCDom_reduced4AbsSigSum);
358 wire [((sigWidth + 2)/4 - 1):0] notCDom_sigExtraMask;
359 lowMaskLoHi#(clog2(prodWidth + 4) - 2, 0, (sigWidth + 2)/4)
360 lowMask_notCDom_sigExtraMask(
361 notCDom_normDistReduced2[(clog2(prodWidth + 4) - 2):1],
362 notCDom_sigExtraMask
363 );
364 wire notCDom_reduced4SigExtra =
365 |(notCDom_reduced4AbsSigSum & notCDom_sigExtraMask);
366 wire [(sigWidth + 2):0] notCDom_sig =
367 {notCDom_mainSig>>3,
368 (|notCDom_mainSig[2:0]) | notCDom_reduced4SigExtra};
369 wire notCDom_completeCancellation =
370 (notCDom_sig[(sigWidth + 2):(sigWidth + 1)] == 0);
371 wire notCDom_sign =
372 notCDom_completeCancellation ? roundingMode_min
373 : signProd ^ notCDom_signSigSum;
374 /*------------------------------------------------------------------------
375 *------------------------------------------------------------------------*/
376 assign out_isZero =
377 notNaN_addZeros | (!CIsDominant && notCDom_completeCancellation);
378 assign out_sign =
379 ( specialCase && special_signOut)
380 | (!specialCase && CIsDominant && CDom_sign )
381 | (!specialCase && !CIsDominant && notCDom_sign );
382 assign out_sExp = CIsDominant ? CDom_sExp : notCDom_sExp;
383 assign out_sig = CIsDominant ? CDom_sig : notCDom_sig;
384
385 endmodule
386
387 /*----------------------------------------------------------------------------
388 *----------------------------------------------------------------------------*/
389
390 module
391 mulAddRecFNToRaw#(parameter expWidth = 3, parameter sigWidth = 3) (
392 input [(`floatControlWidth - 1):0] control,
393 input [1:0] op,
394 input [(expWidth + sigWidth):0] a,
395 input [(expWidth + sigWidth):0] b,
396 input [(expWidth + sigWidth):0] c,
397 input [2:0] roundingMode,
398 output invalidExc,
399 output out_isNaN,
400 output out_isInf,
401 output out_isZero,
402 output out_sign,
403 output signed [(expWidth + 1):0] out_sExp,
404 output [(sigWidth + 2):0] out_sig
405 );
406 `include "HardFloat_localFuncs.vi"
407
408 wire [(sigWidth - 1):0] mulAddA, mulAddB;
409 wire [(sigWidth*2 - 1):0] mulAddC;
410 wire [5:0] intermed_compactState;
411 wire signed [(expWidth + 1):0] intermed_sExp;
412 wire [(clog2(sigWidth + 1) - 1):0] intermed_CDom_CAlignDist;
413 wire [(sigWidth + 1):0] intermed_highAlignedSigC;
414 mulAddRecFNToRaw_preMul#(expWidth, sigWidth)
415 mulAddToRaw_preMul(
416 control,
417 op,
418 a,
419 b,
420 c,
421 roundingMode,
422 mulAddA,
423 mulAddB,
424 mulAddC,
425 intermed_compactState,
426 intermed_sExp,
427 intermed_CDom_CAlignDist,
428 intermed_highAlignedSigC
429 );
430 wire [sigWidth*2:0] mulAddResult = mulAddA * mulAddB + mulAddC;
431 mulAddRecFNToRaw_postMul#(expWidth, sigWidth)
432 mulAddToRaw_postMul(
433 intermed_compactState,
434 intermed_sExp,
435 intermed_CDom_CAlignDist,
436 intermed_highAlignedSigC,
437 mulAddResult,
438 roundingMode,
439 invalidExc,
440 out_isNaN,
441 out_isInf,
442 out_isZero,
443 out_sign,
444 out_sExp,
445 out_sig
446 );
447
448 endmodule
449
450 /*----------------------------------------------------------------------------
451 *----------------------------------------------------------------------------*/
452
453 module
454 mulAddRecFN#(parameter expWidth = 3, parameter sigWidth = 3) (
455 input [(`floatControlWidth - 1):0] control,
456 input [1:0] op,
457 input [(expWidth + sigWidth):0] a,
458 input [(expWidth + sigWidth):0] b,
459 input [(expWidth + sigWidth):0] c,
460 input [2:0] roundingMode,
461 output [(expWidth + sigWidth):0] out,
462 output [4:0] exceptionFlags
463 );
464
465 wire invalidExc, out_isNaN, out_isInf, out_isZero, out_sign;
466 wire signed [(expWidth + 1):0] out_sExp;
467 wire [(sigWidth + 2):0] out_sig;
468 mulAddRecFNToRaw#(expWidth, sigWidth)
469 mulAddRecFNToRaw(
470 control,
471 op,
472 a,
473 b,
474 c,
475 roundingMode,
476 invalidExc,
477 out_isNaN,
478 out_isInf,
479 out_isZero,
480 out_sign,
481 out_sExp,
482 out_sig
483 );
484 roundRawFNToRecFN#(expWidth, sigWidth, 0)
485 roundRawOut(
486 control,
487 invalidExc,
488 1'b0,
489 out_isNaN,
490 out_isInf,
491 out_isZero,
492 out_sign,
493 out_sExp,
494 out_sig,
495 roundingMode,
496 out,
497 exceptionFlags
498 );
499
500 endmodule
501