module __hfloat16__fma( input wire [15:0] a, input wire [15:0] b, input wire [15:0] c, output wire [15:0] out ); // lint_off MULTIPLY function automatic [21:0] umul22b_11b_x_11b (input reg [10:0] lhs, input reg [10:0] rhs); begin umul22b_11b_x_11b = lhs * rhs; end endfunction // lint_on MULTIPLY function automatic priority_sel_1b_2way (input reg [1:0] sel, input reg case0, input reg case1, input reg default_value); begin casez (sel) 2'b?1: begin priority_sel_1b_2way = case0; end 2'b10: begin priority_sel_1b_2way = case1; end 2'b00: begin priority_sel_1b_2way = default_value; end default: begin // Propagate X priority_sel_1b_2way = 1'dx; end endcase end endfunction wire [4:0] a_bexp__1; wire [4:0] b_bexp__1; wire cancel__1; wire bnot__1; wire [9:0] a_fraction__1; wire [9:0] b_fraction__1; wire eq_2034; wire eq_2035; wire [10:0] a_significand__1; wire [10:0] b_significand__1; wire nor_2040; wire [5:0] add_2041; wire [21:0] umul_2042; wire [4:0] max_exp; wire [21:0] full_product; wire eq_2049; wire eq_2050; wire eq_2051; wire eq_2052; wire [6:0] exp; wire in_upper_binade; wire [6:0] exp__1; wire has_inf_arg; wire [6:0] result_exp__1; wire [6:0] result_exp__3; wire is_subnormal; wire has_0_arg; wire is_result_nan__1; wire [5:0] result_exp; wire [4:0] c_bexp__2; wire [5:0] ab_bexp__2; wire [4:0] bnot__2; wire [6:0] ab_bexp_extended__1; wire [6:0] bnot_extended__2; wire [6:0] full_result; wire overflow_detected; wire nc; wire [5:0] narrowed_result; wire [5:0] ab_bexpor_mask__2; wire [21:0] result_fraction__1; wire [5:0] result; wire [21:0] result_fraction__2; wire [5:0] exp_difference; wire [21:0] result_fraction__5; wire [5:0] rshift_ab; wire [9:0] c_fraction__2; wire [5:0] rshift_c; wire [21:0] ab_fraction__2; wire [33:0] shll_2111; wire [10:0] sign_ext_2113; wire [33:0] shll_2114; wire a_sign__1; wire b_sign__1; wire [10:0] wide_c__3; wire result_sign__3; wire [33:0] wide_ab; wire [33:0] wide_c__2; wire [33:0] shifted_ab; wire [33:0] sticky_ab; wire [33:0] shifted_c; wire [33:0] sticky_c; wire c_sign__2; wire ab_sign__2; wire greater_sign; wire [34:0] shifted_ab__1_squeezed; wire [34:0] shifted_c__1_squeezed; wire [34:0] shifted_ab__2_squeezed; wire [34:0] shifted_c__2_squeezed; wire [35:0] shifted_ab__2; wire [35:0] shifted_c__2; wire [35:0] sum_fraction; wire [34:0] abs_fraction__2; wire [34:0] reverse_2161; wire [35:0] one_hot_2162; wire [5:0] encode_2163; wire cancel__2; wire carry_bit__2; wire [6:0] add_2172; wire [33:0] carry_fraction__1; wire [2:0] concat_2180; wire [33:0] carry_fraction__4; wire [33:0] cancel_fraction__2; wire [33:0] shifted_fraction; wire [22:0] normal_chunk; wire [22:0] half_of_extra; wire [1:0] half_way_chunk; wire [11:0] concat_2192; wire [11:0] add_2195; wire [11:0] rounded_fraction__1; wire [5:0] greater_exp; wire rounding_carry; wire [5:0] sub_2203; wire fraction_is_zero; wire [6:0] bexp_associative_element__1; wire [6:0] bexp_associative_element__4; wire [6:0] bexp__1; wire [6:0] bexp__2; wire eq_2218; wire eq_2219; wire eq_2220; wire eq_2221; wire [5:0] bexp__6; wire and_2226; wire is_operand_inf; wire and_reduce_2235; wire has_pos_inf; wire has_neg_inf; wire is_result_nan; wire result_sign; wire [9:0] result_fraction; wire result_sign__1; wire [9:0] result_fraction__3; wire [3:0] one_hot_2265; wire result_sign__2; wire [4:0] result_exp__2; wire [9:0] result_fraction__4; wire nand_2258; wire eq_2267; assign a_bexp__1 = a[14:10]; assign b_bexp__1 = b[14:10]; assign cancel__1 = 1'h0; assign bnot__1 = 1'h1; assign a_fraction__1 = a[9:0]; assign b_fraction__1 = b[9:0]; assign eq_2034 = a_bexp__1 == 5'h00; assign eq_2035 = b_bexp__1 == 5'h00; assign a_significand__1 = {bnot__1, a_fraction__1}; assign b_significand__1 = {bnot__1, b_fraction__1}; assign nor_2040 = ~(eq_2034 | eq_2035); assign add_2041 = {cancel__1, a_bexp__1} + {cancel__1, b_bexp__1}; assign umul_2042 = umul22b_11b_x_11b(a_significand__1, b_significand__1); assign max_exp = 5'h1f; assign full_product = umul_2042 & {22{nor_2040}}; assign eq_2049 = a_bexp__1 == max_exp; assign eq_2050 = a_fraction__1 == 10'h000; assign eq_2051 = b_bexp__1 == max_exp; assign eq_2052 = b_fraction__1 == 10'h000; assign exp = {cancel__1, add_2041} + 7'h71; assign in_upper_binade = full_product[21]; assign exp__1 = exp & {7{nor_2040}}; assign has_inf_arg = eq_2049 & eq_2050 | eq_2051 & eq_2052; assign result_exp__1 = exp__1 + {6'h00, in_upper_binade}; assign result_exp__3 = has_inf_arg ? 7'h3f : result_exp__1; assign is_subnormal = $signed(result_exp__3) <= $signed(7'h00); assign has_0_arg = eq_2034 | eq_2035; assign is_result_nan__1 = ~(~eq_2049 | eq_2050) | ~(~eq_2051 | eq_2052) | has_0_arg & has_inf_arg; assign result_exp = result_exp__3[5:0] & {6{~is_subnormal}}; assign c_bexp__2 = c[14:10]; assign ab_bexp__2 = is_result_nan__1 ? 6'h3f : result_exp; assign bnot__2 = ~c_bexp__2; assign ab_bexp_extended__1 = {cancel__1, ab_bexp__2}; assign bnot_extended__2 = {2'h1, bnot__2}; assign full_result = ab_bexp_extended__1 + bnot_extended__2; assign overflow_detected = full_result[6]; assign nc = ~overflow_detected; assign narrowed_result = full_result[5:0]; assign ab_bexpor_mask__2 = {6{nc}}; assign result_fraction__1 = in_upper_binade ? umul_2042 : {full_product[20:0], cancel__1}; assign result = narrowed_result ^ ab_bexpor_mask__2; assign result_fraction__2 = result_fraction__1 & {22{~has_inf_arg}}; assign exp_difference = result + {5'h00, overflow_detected}; assign result_fraction__5 = (-result_exp__3[5:0] & {6{is_subnormal}}) >= 6'h16 ? 22'h00_0000 : result_fraction__2 >> (-result_exp__3[5:0] & {6{is_subnormal}}); assign rshift_ab = exp_difference & ab_bexpor_mask__2; assign c_fraction__2 = c[9:0]; assign rshift_c = exp_difference & {6{overflow_detected}}; assign ab_fraction__2 = is_result_nan__1 ? 22'h30_0000 : result_fraction__5; assign shll_2111 = rshift_ab >= 6'h22 ? 34'h0_0000_0000 : 34'h3_ffff_ffff << rshift_ab; assign sign_ext_2113 = {11{c_bexp__2 != 5'h00}}; assign shll_2114 = rshift_c >= 6'h22 ? 34'h0_0000_0000 : 34'h3_ffff_ffff << rshift_c; assign a_sign__1 = a[15:15]; assign b_sign__1 = b[15:15]; assign wide_c__3 = {bnot__1, c_fraction__2} & sign_ext_2113; assign result_sign__3 = a_sign__1 ^ b_sign__1; assign wide_ab = {ab_fraction__2, 12'h000}; assign wide_c__2 = {wide_c__3, 23'h00_0000}; assign shifted_ab = rshift_ab >= 6'h22 ? 34'h0_0000_0000 : wide_ab >> rshift_ab; assign sticky_ab = {33'h0_0000_0000, ~(~ab_fraction__2 | shll_2111[33:12]) != 22'h00_0000}; assign shifted_c = rshift_c >= 6'h22 ? 34'h0_0000_0000 : wide_c__2 >> rshift_c; assign sticky_c = {33'h0_0000_0000, ~({cancel__1, ~c_fraction__2} | ~sign_ext_2113 | shll_2114[33:23]) != 11'h000}; assign c_sign__2 = c[15:15]; assign ab_sign__2 = ~(is_result_nan__1 | ~result_sign__3); assign greater_sign = overflow_detected ? ab_sign__2 : c_sign__2; assign shifted_ab__1_squeezed = {cancel__1, shifted_ab | sticky_ab}; assign shifted_c__1_squeezed = {cancel__1, shifted_c | sticky_c}; assign shifted_ab__2_squeezed = ab_sign__2 ^ greater_sign ? -shifted_ab__1_squeezed : shifted_ab__1_squeezed; assign shifted_c__2_squeezed = c_sign__2 ^ greater_sign ? -shifted_c__1_squeezed : shifted_c__1_squeezed; assign shifted_ab__2 = {{1{shifted_ab__2_squeezed[34]}}, shifted_ab__2_squeezed}; assign shifted_c__2 = {{1{shifted_c__2_squeezed[34]}}, shifted_c__2_squeezed}; assign sum_fraction = shifted_ab__2 + shifted_c__2; assign abs_fraction__2 = sum_fraction[35] ? -sum_fraction[34:0] : sum_fraction[34:0]; assign reverse_2161 = {abs_fraction__2[0], abs_fraction__2[1], abs_fraction__2[2], abs_fraction__2[3], abs_fraction__2[4], abs_fraction__2[5], abs_fraction__2[6], abs_fraction__2[7], abs_fraction__2[8], abs_fraction__2[9], abs_fraction__2[10], abs_fraction__2[11], abs_fraction__2[12], abs_fraction__2[13], abs_fraction__2[14], abs_fraction__2[15], abs_fraction__2[16], abs_fraction__2[17], abs_fraction__2[18], abs_fraction__2[19], abs_fraction__2[20], abs_fraction__2[21], abs_fraction__2[22], abs_fraction__2[23], abs_fraction__2[24], abs_fraction__2[25], abs_fraction__2[26], abs_fraction__2[27], abs_fraction__2[28], abs_fraction__2[29], abs_fraction__2[30], abs_fraction__2[31], abs_fraction__2[32], abs_fraction__2[33], abs_fraction__2[34]}; assign one_hot_2162 = {reverse_2161[34:0] == 35'h0_0000_0000, reverse_2161[34] && reverse_2161[33:0] == 34'h0_0000_0000, reverse_2161[33] && reverse_2161[32:0] == 33'h0_0000_0000, reverse_2161[32] && reverse_2161[31:0] == 32'h0000_0000, reverse_2161[31] && reverse_2161[30:0] == 31'h0000_0000, reverse_2161[30] && reverse_2161[29:0] == 30'h0000_0000, reverse_2161[29] && reverse_2161[28:0] == 29'h0000_0000, reverse_2161[28] && reverse_2161[27:0] == 28'h000_0000, reverse_2161[27] && reverse_2161[26:0] == 27'h000_0000, reverse_2161[26] && reverse_2161[25:0] == 26'h000_0000, reverse_2161[25] && reverse_2161[24:0] == 25'h000_0000, reverse_2161[24] && reverse_2161[23:0] == 24'h00_0000, reverse_2161[23] && reverse_2161[22:0] == 23'h00_0000, reverse_2161[22] && reverse_2161[21:0] == 22'h00_0000, reverse_2161[21] && reverse_2161[20:0] == 21'h00_0000, reverse_2161[20] && reverse_2161[19:0] == 20'h0_0000, reverse_2161[19] && reverse_2161[18:0] == 19'h0_0000, reverse_2161[18] && reverse_2161[17:0] == 18'h0_0000, reverse_2161[17] && reverse_2161[16:0] == 17'h0_0000, reverse_2161[16] && reverse_2161[15:0] == 16'h0000, reverse_2161[15] && reverse_2161[14:0] == 15'h0000, reverse_2161[14] && reverse_2161[13:0] == 14'h0000, reverse_2161[13] && reverse_2161[12:0] == 13'h0000, reverse_2161[12] && reverse_2161[11:0] == 12'h000, reverse_2161[11] && reverse_2161[10:0] == 11'h000, reverse_2161[10] && reverse_2161[9:0] == 10'h000, reverse_2161[9] && reverse_2161[8:0] == 9'h000, reverse_2161[8] && reverse_2161[7:0] == 8'h00, reverse_2161[7] && reverse_2161[6:0] == 7'h00, reverse_2161[6] && reverse_2161[5:0] == 6'h00, reverse_2161[5] && reverse_2161[4:0] == 5'h00, reverse_2161[4] && reverse_2161[3:0] == 4'h0, reverse_2161[3] && reverse_2161[2:0] == 3'h0, reverse_2161[2] && reverse_2161[1:0] == 2'h0, reverse_2161[1] && !reverse_2161[0], reverse_2161[0]}; assign encode_2163 = {one_hot_2162[32] | one_hot_2162[33] | one_hot_2162[34] | one_hot_2162[35], one_hot_2162[16] | one_hot_2162[17] | one_hot_2162[18] | one_hot_2162[19] | one_hot_2162[20] | one_hot_2162[21] | one_hot_2162[22] | one_hot_2162[23] | one_hot_2162[24] | one_hot_2162[25] | one_hot_2162[26] | one_hot_2162[27] | one_hot_2162[28] | one_hot_2162[29] | one_hot_2162[30] | one_hot_2162[31], one_hot_2162[8] | one_hot_2162[9] | one_hot_2162[10] | one_hot_2162[11] | one_hot_2162[12] | one_hot_2162[13] | one_hot_2162[14] | one_hot_2162[15] | one_hot_2162[24] | one_hot_2162[25] | one_hot_2162[26] | one_hot_2162[27] | one_hot_2162[28] | one_hot_2162[29] | one_hot_2162[30] | one_hot_2162[31], one_hot_2162[4] | one_hot_2162[5] | one_hot_2162[6] | one_hot_2162[7] | one_hot_2162[12] | one_hot_2162[13] | one_hot_2162[14] | one_hot_2162[15] | one_hot_2162[20] | one_hot_2162[21] | one_hot_2162[22] | one_hot_2162[23] | one_hot_2162[28] | one_hot_2162[29] | one_hot_2162[30] | one_hot_2162[31], one_hot_2162[2] | one_hot_2162[3] | one_hot_2162[6] | one_hot_2162[7] | one_hot_2162[10] | one_hot_2162[11] | one_hot_2162[14] | one_hot_2162[15] | one_hot_2162[18] | one_hot_2162[19] | one_hot_2162[22] | one_hot_2162[23] | one_hot_2162[26] | one_hot_2162[27] | one_hot_2162[30] | one_hot_2162[31] | one_hot_2162[34] | one_hot_2162[35], one_hot_2162[1] | one_hot_2162[3] | one_hot_2162[5] | one_hot_2162[7] | one_hot_2162[9] | one_hot_2162[11] | one_hot_2162[13] | one_hot_2162[15] | one_hot_2162[17] | one_hot_2162[19] | one_hot_2162[21] | one_hot_2162[23] | one_hot_2162[25] | one_hot_2162[27] | one_hot_2162[29] | one_hot_2162[31] | one_hot_2162[33] | one_hot_2162[35]}; assign cancel__2 = |encode_2163[5:1]; assign carry_bit__2 = abs_fraction__2[34]; assign add_2172 = {cancel__1, encode_2163} + 7'h7f; assign carry_fraction__1 = abs_fraction__2[34:1]; assign concat_2180 = {~(carry_bit__2 | cancel__2), ~(carry_bit__2 | ~cancel__2), ~(~carry_bit__2 | cancel__2)}; assign carry_fraction__4 = carry_fraction__1 | {33'h0_0000_0000, abs_fraction__2[0]}; assign cancel_fraction__2 = {{28{add_2172[6]}}, add_2172} >= 35'h0_0000_0022 ? 34'h0_0000_0000 : abs_fraction__2[33:0] << {{28{add_2172[6]}}, add_2172}; assign shifted_fraction = carry_fraction__4 & {34{concat_2180[0]}} | cancel_fraction__2 & {34{concat_2180[1]}} | abs_fraction__2[33:0] & {34{concat_2180[2]}}; assign normal_chunk = shifted_fraction[22:0]; assign half_of_extra = 23'h40_0000; assign half_way_chunk = shifted_fraction[23:22]; assign concat_2192 = {cancel__1, shifted_fraction[33:23]}; assign add_2195 = concat_2192 + 12'h001; assign rounded_fraction__1 = normal_chunk > half_of_extra | half_way_chunk == 2'h3 ? add_2195 : concat_2192; assign greater_exp = overflow_detected ? ab_bexp__2 : {cancel__1, c_bexp__2}; assign rounding_carry = rounded_fraction__1[11]; assign sub_2203 = 6'h00 - {cancel__1, encode_2163[5:1]}; assign fraction_is_zero = sum_fraction == 36'h0_0000_0000; assign bexp_associative_element__1 = {sub_2203, ~encode_2163[0]}; assign bexp_associative_element__4 = {cancel__1, greater_exp} + {6'h00, rounding_carry}; assign bexp__1 = bexp_associative_element__1 + bexp_associative_element__4; assign bexp__2 = bexp__1 & {7{~fraction_is_zero}}; assign eq_2218 = ab_bexp__2 == 6'h3f; assign eq_2219 = ab_fraction__2 == 22'h00_0000; assign eq_2220 = c_bexp__2 == max_exp; assign eq_2221 = c_fraction__2 == 10'h000; assign bexp__6 = bexp__2[5:0] & {6{~bexp__2[6]}}; assign and_2226 = eq_2218 & eq_2219; assign is_operand_inf = and_2226 | eq_2220 & eq_2221; assign and_reduce_2235 = &bexp__6[4:0]; assign has_pos_inf = ~(~(eq_2218 & eq_2219) | ab_sign__2) | ~(~eq_2220 | ~eq_2221 | c_sign__2); assign has_neg_inf = and_2226 & ab_sign__2 | eq_2220 & eq_2221 & c_sign__2; assign is_result_nan = ~(~eq_2218 | eq_2219) | ~(~eq_2220 | eq_2221) | has_pos_inf & has_neg_inf; assign result_sign = priority_sel_1b_2way({sum_fraction[35], fraction_is_zero}, cancel__1, ~greater_sign, greater_sign); assign result_fraction = rounded_fraction__1[9:0]; assign result_sign__1 = is_operand_inf ? ~has_pos_inf : result_sign; assign result_fraction__3 = result_fraction & {10{~(is_operand_inf | bexp__6[5] | and_reduce_2235 | bexp__6 == 6'h00)}}; assign one_hot_2265 = {concat_2180[2:0] == 3'h0, concat_2180[2] && concat_2180[1:0] == 2'h0, concat_2180[1] && !concat_2180[0], concat_2180[0]}; assign result_sign__2 = ~is_result_nan & result_sign__1; assign result_exp__2 = is_result_nan | is_operand_inf | bexp__6[5] | and_reduce_2235 ? max_exp : bexp__6[4:0]; assign result_fraction__4 = is_result_nan ? 10'h040 : result_fraction__3; assign nand_2258 = ~(carry_bit__2 & cancel__2); assign eq_2267 = concat_2180 == one_hot_2265[2:0]; assign out = {result_sign__2, result_exp__2, result_fraction__4}; endmodule