////// // Please consider this function a black box. DO NOT try to copy any part of this function in your code. ////// function [31:0] multiplication (string round, logic [31:0] a, logic [31:0] b); bit [31:0] result; // Convert every denormal in zero if(a[30:23] == '0) a[22:0] = '0; if(b[30:23] == '0) b[22:0] = '0; if(a[30:23] == '1) a[22:0] = '0; if(b[30:23] == '1) b[22:0] = '0; // If (a is inf or NaN) or (b is inf or NaN) => Result Inf if((a[30:23] == '1 && b[30:23] == '0) || (a[30:23] == '0 && b[30:23] == '1)) result = {1'b0, {8{1'b1}}, {23{1'b0}}}; else begin result = $shortrealtobits($bitstoshortreal(a) * $bitstoshortreal(b)); case (round) //IEEE_NEAR ROUNDING "IEEE_near": begin if(result[30:23] == '1) result[22:0] = '0; if(result[30:23] == '0) result[22:0] = '0; end //IEEE_ZERO ROUNDING "IEEE_zero": begin //Round towards zero instead if rounded up and positive if($bitstoshortreal(result) > ($bitstoshortreal(a) * $bitstoshortreal(b))) begin if($bitstoshortreal(result) > 0) begin result = result - 1; end end //Round towards zero instead if rounded down and negative if($bitstoshortreal(result) < ($bitstoshortreal(a) * $bitstoshortreal(b))) begin if($bitstoshortreal(result) < 0) begin result = result - 1; end end if(result[30:23] == '0) result[22:0] = '0; end //AWAY_ZERO ROUNDING "away_zero": begin //Check if the result is denormal and round to minNormal if((result[30:23] == '0 && result[22:0] != '0) || (a[30:23] != '0 && b[30:23] != '0 && result[30:23] == '0 && result[22:0] == '0)) begin result = {result[31], {7{1'b0}}, 1'b1, {23{1'b0}}}; end else begin //Round away from zero instead if rounded up and negative if($bitstoshortreal(result) > ($bitstoshortreal(a) * $bitstoshortreal(b))) begin if($bitstoshortreal(result) < 0) begin result = result + 1; end end //Round away from zero instead if rounded down and positive if($bitstoshortreal(result) < ($bitstoshortreal(a) * $bitstoshortreal(b))) begin if($bitstoshortreal(result) > 0) begin result = result + 1; end end end if(result[30:23] == '1) result[22:0] = '0; end //IEEE_PINF ROUNDING "IEEE_pinf": begin //Check if the result is denormal and round to minNormal, but only for positives if((result[31] == 0 && result[30:23] == '0 && result[22:0] != '0) || (result[31] == 0 && a[30:23] != '0 && b[30:23] != '0 && result[30:23] == '0 && result[22:0] == '0)) begin result = {{8{1'b0}}, 1'b1, {23{1'b0}}}; end else begin //Round towards positive infinity instead if rounded down and positive if($bitstoshortreal(result) < ($bitstoshortreal(a) * $bitstoshortreal(b))) begin if($bitstoshortreal(result) > 0) begin result = result + 1; end end //Round towards positive infinity instead if rounded down and negative if($bitstoshortreal(result) < ($bitstoshortreal(a) * $bitstoshortreal(b))) begin if($bitstoshortreal(result) < 0) begin result = result - 1; end end end if(result[30:23] == '0) result[22:0] = '0; end //IEEE_NINF ROUNDING "IEEE_ninf": begin //Check if the result is denormal and round to minNormal, but only for negatives if((result[31] == 1 && result[30:23] == '0 && result[22:0] != '0) || (result[31] == 1 && a[30:23] != '0 && b[30:23] != '0 && result[30:23] == '0 && result[22:0] == '0)) begin result = {1'b1, {7{1'b0}}, 1'b1, {23{1'b0}}}; end else begin //Round towards negative infinity instead if rounded up and positive if($bitstoshortreal(result) > ($bitstoshortreal(a) * $bitstoshortreal(b))) begin if($bitstoshortreal(result) > 0) begin result = result - 1; end end //Round towards negative infinity instead if rounded up and negative if($bitstoshortreal(result) > ($bitstoshortreal(a) * $bitstoshortreal(b))) begin if($bitstoshortreal(result) < 0) begin result = result + 1; end end end if(result[30:23] == '0) result[22:0] = '0; end //NEAR_UP ROUNDING "near_up": begin //Round towards positive infinity if rounded down, negative and in the middle if(($bitstoshortreal(result) < ($bitstoshortreal(a) * $bitstoshortreal(b)))) begin if(($bitstoshortreal(result) - ($bitstoshortreal(a) * $bitstoshortreal(b))) == (($bitstoshortreal(a) * $bitstoshortreal(b)) - $bitstoshortreal(result-1))) begin if($bitstoshortreal(result) < 0) begin result = result - 1; end end end //Round towards positive infinity if rounded down, positive and in the middle if(($bitstoshortreal(result) < ($bitstoshortreal(a) * $bitstoshortreal(b)))) begin if(($bitstoshortreal(result+1) - ($bitstoshortreal(a) * $bitstoshortreal(b))) == (($bitstoshortreal(a) * $bitstoshortreal(b)) - $bitstoshortreal(result))) begin if($bitstoshortreal(result) > 0) begin result = result + 1; end end end if(result[30:23] == '1) result[22:0] = '0; if(result[30:23] == '0) result[22:0] = '0; end endcase end return result; endfunction