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