| |
| //mains modue of FMADD |
| |
| //including coommon blocks |
| |
| /*`include "FMADD_M_G.v" |
| `include "FMADD_Ext.v" |
| `include "F_LZD_Main.v" |
| `include "fma_LZD_L0.v" |
| `include "fma_LZD_L1.v" |
| `include "fma_LZD_L2.v" |
| `include "fma_LZD_L3.v" |
| `include "fma_LZD_L4.v" |
| |
| //including Multiplication LANE |
| `include "FMADD_E_A.v" |
| `include "FMADD_mult.v" |
| `include "FMADD_PN_Mul.v" |
| `include "FMADD_RB_MUL.v" |
| |
| //Includign Addition/Subtraction LANE |
| `include "FMADD_E_M.v" |
| `include "FMADD_M_A.v" |
| `include "FMADD_PN_Ad.v" |
| `include "FMADD_RB_Ad.v"*/ |
| |
| |
| |
| module FPU_FMADD_SUBB_Top (FMADD_SUBB_input_IEEE_A, FMADD_SUBB_input_IEEE_B, FMADD_SUBB_input_IEEE_C, FMADD_SUBB_input_opcode,rst_l,FMADD_SUBB_input_Frm,FMADD_SUBB_output_IEEE_FMADD, FMADD_SUBB_output_S_Flags_FMADD, FMADD_SUBB_output_IEEE_FMUL, FMADD_SUBB_output_S_Flags_FMUL ); |
| |
| parameter std =31; |
| parameter man =22; |
| parameter exp =7; |
| parameter bias = 127; |
| parameter lzd = 4; |
| |
| //declaration of inputs |
| input [std:0] FMADD_SUBB_input_IEEE_A, FMADD_SUBB_input_IEEE_B,FMADD_SUBB_input_IEEE_C; |
| input [6:0] FMADD_SUBB_input_opcode; |
| input [2:0] FMADD_SUBB_input_Frm; |
| input rst_l; |
| |
| //Opcodes description |
| /* |
| Opcodes[0] = Fadd |
| Opcodes[1] = Fsubb |
| Opcodes[2] = Fmul |
| Opcodes[3] = Fmadd |
| Opcodes[4] = Fmsubb |
| Opcodes[5] = Fnmadd |
| Opcodes[6] = Fnmsubb |
| */ |
| |
| //declaration of putputs |
| output [std:0] FMADD_SUBB_output_IEEE_FMADD, FMADD_SUBB_output_IEEE_FMUL; |
| output [2:0] FMADD_SUBB_output_S_Flags_FMADD , FMADD_SUBB_output_S_Flags_FMUL; |
| //output FMADD_SUBB_output_FMADD_Ready_Flag; |
| |
| //instantiation of sub modules |
| //mantissa generation modules: This module concatenates the hidden bit, and sets the exponent in accordance with the type of number (Normal Sub_Normal) |
| |
| //activation isgnal for multiplication lane |
| wire Activation_signal_MUL,Activation_signal; |
| wire [std:0] input_interim_Mantissa_gnerator_A,input_interim_Mantissa_gnerator_B,input_interim_Mantissa_gnerator_C; |
| wire [std+1:0] output_interim_M_G_A,output_interim_M_G_B,output_interim_M_G_C; |
| wire output_interim_A_sub_norm,output_interim_B_sub_norm,output_interim_A_pos_exp,output_interim_B_pos_exp,output_interim_A_neg_exp,output_interim_B_neg_exp; |
| |
| |
| //Reset condition |
| assign input_interim_Mantissa_gnerator_A = (rst_l) ? FMADD_SUBB_input_IEEE_A : { std+1 {1'b0} }; |
| assign input_interim_Mantissa_gnerator_B = (rst_l) ? FMADD_SUBB_input_IEEE_B : { std+1 {1'b0} }; |
| assign input_interim_Mantissa_gnerator_C = (rst_l) ? FMADD_SUBB_input_IEEE_C : { std+1 {1'b0} }; |
| assign Activation_signal_MUL = (rst_l) ? ( |(FMADD_SUBB_input_opcode[6:2]) ) : 1'b0; |
| assign Activation_signal = (rst_l) ? ( | (FMADD_SUBB_input_opcode[6:0])) : 1'b0; |
| |
| FMADD_Mantissa_Generator Mantissa_Generator ( |
| .Mantissa_Generator_input_IEEE_A (input_interim_Mantissa_gnerator_A), |
| .Mantissa_Generator_input_IEEE_B (input_interim_Mantissa_gnerator_B), |
| .Mantissa_Generator_input_IEEE_C (input_interim_Mantissa_gnerator_C), |
| .Mantissa_Generator_input_Activation_signal (Activation_signal), |
| .Mantissa_Generator_output_A_Sub_norm(output_interim_A_sub_norm), |
| .Mantissa_Generator_output_B_Sub_norm(output_interim_B_sub_norm), |
| .Mantissa_Generator_output_A_pos_exp(output_interim_A_pos_exp), |
| .Mantissa_Generator_output_B_pos_exp(output_interim_B_pos_exp), |
| .Mantissa_Generator_output_A_neg_exp(output_interim_A_neg_exp), |
| .Mantissa_Generator_output_B_neg_exp(output_interim_B_neg_exp), |
| .Mantissa_Generator_output_IEEE_A (output_interim_M_G_A), |
| .Mantissa_Generator_output_IEEE_B (output_interim_M_G_B), |
| .Mantissa_Generator_output_IEEE_C (output_interim_M_G_C) |
| ); |
| defparam Mantissa_Generator.std = std; |
| defparam Mantissa_Generator.man = man; |
| defparam Mantissa_Generator.exp = exp; |
| |
| //extend module : This module is responsible for making the input representable in IEEE exteded format |
| wire [std+1 : 0] input_Extender_B; |
| wire [2+exp+2*(man+2):0] output_interim_Extender_A,output_interim_Extender_B; |
| |
| //selection of the second operand of the extender : If addition is the inputted instruction B goes to extender otherwise C goes to the Extender |
| assign input_Extender_B = (| FMADD_SUBB_input_opcode[1:0]) ? output_interim_M_G_B : output_interim_M_G_C; |
| FMADD_Extender Extender ( |
| .Extender_input_A(output_interim_M_G_A), |
| .Extender_input_B(input_Extender_B), |
| .Extender_output_A(output_interim_Extender_A), |
| .Extender_output_B(output_interim_Extender_B) |
| ); |
| defparam Extender.std = std; |
| defparam Extender.man = man; |
| defparam Extender.exp = exp; |
| |
| //exponent addition module: This module is repsonsible for carrying out tje first operation of Multiplication i.e.e exponent addition |
| wire [4:0] input_interim_exponent_addition_opcodes; |
| wire input_Exponent_Addition_input_Sign_A; |
| wire [exp+1 : 0] output_interim_exponent_addition; |
| wire output_interim_exponent_addition_sign; |
| wire underflow_FMUL; |
| |
| assign input_Exponent_Addition_input_Sign_A = ( |FMADD_SUBB_input_opcode[6:5] ) ? (~output_interim_M_G_A[std+1]) : (output_interim_M_G_A[std+1]) ; |
| |
| FMADD_Exponent_addition Exponent_Addition ( |
| .Exponent_addition_input_A({ input_Exponent_Addition_input_Sign_A, output_interim_M_G_A[std:man+2] } ), |
| .Exponent_addition_input_B(output_interim_M_G_B[std+1:man+2]), |
| .Exponent_addition_input_Activation_Signal (Activation_signal_MUL), |
| .Exponent_addition_output_exp(output_interim_exponent_addition), |
| .output_underflow_check (underflow_FMUL), |
| .Exponent_addition_output_sign(output_interim_exponent_addition_sign) |
| ); |
| defparam Exponent_Addition.std = std; |
| defparam Exponent_Addition.man = man; |
| defparam Exponent_Addition.exp = exp; |
| |
| |
| //mantissa multiplication Module |
| wire [man+man+3 :0] output_interim_mantissa_multiplication; |
| |
| FMADD_Mantissa_Multiplication Mantissa_Multiplication ( |
| .Mantissa_Multiplication_input_A(output_interim_M_G_A[man+1:0]), |
| .Mantissa_Multiplication_input_B(output_interim_M_G_B[man+1:0]), |
| .Mantissa_Multiplication_input_Activation_Signal (Activation_signal_MUL), |
| .Mantissa_Multiplication_output_Mantissa( output_interim_mantissa_multiplication) |
| ); |
| defparam Mantissa_Multiplication.man = man; |
| defparam Mantissa_Multiplication.exp = exp; |
| |
| //instantiation of LZD module |
| wire [23:0] input_LZD; |
| //wire [4:0] output_LZD; |
| wire [lzd : 0] output_LZD; |
| |
| |
| wire [23 : 0] input_interim_A_LZD, input_interim_B_LZD ; |
| |
| assign input_interim_A_LZD = |
| (man == 22) ? (output_interim_M_G_A[man+1:0]) : //-8 for SP |
| (man == 9 ) ? ({ ({(24-(man+2)){1'b0}}) ,(output_interim_M_G_A[man+1:0])}) : //-21 for IEEE16, concatinate 24-(man+2) zero to make the mantissa size == 24 |
| ({ ({(24-(man+2)){1'b0}}) ,(output_interim_M_G_A[man+1:0])}) ; //-24 for Bf16, concatinate 24-(man+2) zero to make the mantissa size == 24 |
| assign input_interim_B_LZD = |
| (man == 22) ? (output_interim_M_G_B[man+1:0]) : //-8 for SP |
| (man == 9 ) ? ({ ({(24-(man+2)){1'b0}}) ,(output_interim_M_G_B[man+1:0])}) : //-21 for IEEE16, concatinate 24-(man+2) zero to make the mantissa size == 24 |
| ({ ({(24-(man+2)){1'b0}}) ,(output_interim_M_G_B[man+1:0])}) ; //-24 for Bf16, concatinate 24-(man+2) zero to make the mantissa size == 24 |
| |
| assign input_LZD = (output_interim_A_sub_norm) ? input_interim_A_LZD : input_interim_B_LZD ; |
| |
| |
| //assign input_LZD = (output_interim_A_sub_norm) ? output_interim_M_G_A[man+1:0] : output_interim_M_G_B[man+1:0] ; |
| |
| |
| FMADD_PN_LZD Leading_Zero_detection ( |
| .FMADD_PN_LZD_input_man_48(input_LZD), |
| .FMADD_PN_LZD_output_pos(output_LZD) |
| ); |
| defparam Leading_Zero_detection.man = man; |
| defparam Leading_Zero_detection.lzd = lzd; |
| |
| //post normalaization Module |
| wire [2+exp+2*(man+2):0] output_interim_post_normalization_IEEE_A; |
| wire output_interim_post_normalization_mul_sticky; |
| |
| FMADD_PN_MUL Post_Normalization_Mul ( |
| . FMADD_PN_MUL_input_sign (output_interim_exponent_addition_sign), |
| . FMADD_PN_MUL_input_multiplied_man (output_interim_mantissa_multiplication), |
| . FMADD_PN_MUL_input_exp_DB (output_interim_exponent_addition), |
| . FMADD_PN_MUL_input_lzd (output_LZD), |
| . FMADD_PN_MUL_input_A_sub (output_interim_A_sub_norm), |
| . FMADD_PN_MUL_input_B_sub (output_interim_B_sub_norm), |
| . FMADD_PN_MUL_input_A_pos (output_interim_A_pos_exp), |
| . FMADD_PN_MUL_input_B_pos (output_interim_B_pos_exp), |
| . FMADD_PN_MUL_input_A_neg (output_interim_A_neg_exp), |
| . FMADD_PN_MUL_input_B_neg (output_interim_B_neg_exp), |
| . FMADD_PN_MUL_output_no (output_interim_post_normalization_IEEE_A), |
| . FMADD_PN_MUL_output_sticky_PN(output_interim_post_normalization_mul_sticky), |
| . FMADD_PN_MUL_input_rm(FMADD_SUBB_input_Frm) |
| ); |
| |
| defparam Post_Normalization_Mul.std = std; |
| defparam Post_Normalization_Mul.exp = exp; |
| defparam Post_Normalization_Mul.man = man; |
| defparam Post_Normalization_Mul.bias = bias; |
| defparam Post_Normalization_Mul.lzd = lzd; |
| |
| //module instantiatyion of Rounding Block of Multipliction Lane |
| wire [std:0] output_rounding_Block; |
| wire [2:0] output_interim_rounding_Block_S_Flag; |
| |
| FMADD_ROUND_MUL Rounding_Block_Mul ( |
| .FMADD_ROUND_MUL_input_sticky_PN(output_interim_post_normalization_mul_sticky), |
| .FMADD_ROUND_MUL_input_no(output_interim_post_normalization_IEEE_A), |
| .FMADD_ROUND_MUL_input_rm(FMADD_SUBB_input_Frm), |
| .FMADD_ROUND_MUL_output_no(output_rounding_Block), |
| .FMADD_ROUND_MUL_output_S_Flags(output_interim_rounding_Block_S_Flag) |
| ); |
| defparam Rounding_Block_Mul.std = std; |
| defparam Rounding_Block_Mul.exp = exp; |
| defparam Rounding_Block_Mul.man = man; |
| |
| //module instantiation of FMADD Lane |
| ///=interim wires and register for FMADD Lane |
| |
| //ppelining registers |
| wire [2+exp+2*(man+2):0] input_interim_ADD_LANE_A; |
| wire [2+exp+2*(man+2):0] input_interim_ADD_LANE_B; |
| wire [2+exp+2*(man+2):0] output_interim_post_normalization_IEEE; |
| |
| //inputs to the FMADD LANE |
| assign input_interim_ADD_LANE_A = ( |(FMADD_SUBB_input_opcode[1:0] ) ) ? output_interim_Extender_A : (| FMADD_SUBB_input_opcode[6:3]) ? output_interim_post_normalization_IEEE : 57'h000000000000000 ; |
| assign input_interim_ADD_LANE_B = (|(FMADD_SUBB_input_opcode[1:0] ) ) ? output_interim_Extender_B : (| FMADD_SUBB_input_opcode[6:3]) ? output_interim_Extender_B : 57'h000000000000000; |
| |
| //exponent_Matching |
| wire output_interim_Exponent_Mathcing_Sign; |
| wire [man+man+3:0] output_interim_Exponent_Mathcing_Mantissa_A; |
| wire [man+man+3:0] output_interim_Exponent_Mathcing_Mantissa_B; |
| wire [exp+1:0] output_interim_Exponent_Mathcing_Exponent; |
| wire output_interim_Exponent_Mathcing_Eff_add; |
| wire output_interim_Exponent_Mathcing_Eff_sub; |
| wire output_interim_Exponent_Mathcing_Guard; |
| wire output_interim_Exponent_Mathcing_Round; |
| wire output_interim_Exponent_Mathcing_Sticky; |
| wire output_interim_Exponent_Mathcing_Exp_Diff_Check; |
| wire output_interim_Exponent_Mathcing_A_gt_B; |
| |
| |
| assign output_interim_post_normalization_IEEE = ( (&(~output_interim_post_normalization_IEEE_A[1+exp+2*(man+2):man+man+4])) & (~underflow_FMUL) ) ? {output_interim_post_normalization_IEEE_A[2+exp+2*(man+2)],{exp+1{1'b0}},1'b1,output_interim_post_normalization_IEEE_A[man+man+3:0] } : output_interim_post_normalization_IEEE_A ; |
| |
| FMADD_Exponent_Matching Exponent_Matching ( |
| .Exponent_Matching_input_Sign_A ( input_interim_ADD_LANE_A[2+exp+2*(man+2)] ), |
| .Exponent_Matching_input_Sign_B( input_interim_ADD_LANE_B[2+exp+2*(man+2)] ), |
| .Exponent_Matching_input_Exp_A( input_interim_ADD_LANE_A[1+exp+2*(man+2): man+man+4] ), |
| .Exponent_Matching_input_Exp_B( input_interim_ADD_LANE_B[1+exp+2*(man+2): man+man+4] ), |
| .Exponent_Matching_input_Mantissa_A( input_interim_ADD_LANE_A[man+man+3 : 0] ), |
| .Exponent_Matching_input_Mantissa_B( input_interim_ADD_LANE_B[man+man+3 : 0] ), |
| .Exponent_Matching_input_opcode( { FMADD_SUBB_input_opcode[1] | FMADD_SUBB_input_opcode[4] | FMADD_SUBB_input_opcode[6] , FMADD_SUBB_input_opcode[0] | FMADD_SUBB_input_opcode[5] | FMADD_SUBB_input_opcode[3]} ), |
| .Exponent_Matching_output_Mantissa_A( output_interim_Exponent_Mathcing_Mantissa_A), |
| .Exponent_Matching_output_Mantissa_B( output_interim_Exponent_Mathcing_Mantissa_B), |
| .Exponent_Matching_output_Exp (output_interim_Exponent_Mathcing_Exponent), |
| .Exponent_Matching_output_Sign( output_interim_Exponent_Mathcing_Sign), |
| .Exponent_Matching_output_Guard (output_interim_Exponent_Mathcing_Guard), |
| .Exponent_Matching_output_Round( output_interim_Exponent_Mathcing_Round), |
| .Exponent_Matching_output_Sticky( output_interim_Exponent_Mathcing_Sticky), |
| .Exponent_Matching_output_Eff_Sub( output_interim_Exponent_Mathcing_Eff_sub), |
| .Exponent_Matching_output_Eff_add( output_interim_Exponent_Mathcing_Eff_add), |
| .Exponent_Matching_output_Exp_Diff_Check (output_interim_Exponent_Mathcing_Exp_Diff_Check), |
| .Exponent_Matching_output_A_gt_B (output_interim_Exponent_Mathcing_A_gt_B) |
| ); |
| defparam Exponent_Matching.std = std; |
| defparam Exponent_Matching.exp = exp; |
| defparam Exponent_Matching.man = man; |
| |
| |
| //Mantissa Addition |
| wire [man+man+3:0] output_interim_Mantissa_Addition_Mantissa; |
| wire output_interim_Mantissa_Addition_Carry; |
| FMADD_Mantissa_Addition Mantissa_Addition ( |
| .Mantissa_Addition_input_Mantissa_A( output_interim_Exponent_Mathcing_Mantissa_A), |
| .Mantissa_Addition_input_Mantissa_B( output_interim_Exponent_Mathcing_Mantissa_B), |
| .Mantissa_Addition_input_Eff_Sub( output_interim_Exponent_Mathcing_Eff_sub), |
| .Mantissa_Addition_output_Mantissa(output_interim_Mantissa_Addition_Mantissa ), |
| .Mantissa_Addition_output_Carry(output_interim_Mantissa_Addition_Carry), |
| .Mantissa_Addition_input_Exp_Diff_Check (output_interim_Exponent_Mathcing_Exp_Diff_Check), |
| .Mantissa_Addition_input_A_gt_B(output_interim_Exponent_Mathcing_A_gt_B) |
| ); |
| defparam Mantissa_Addition.std = std; |
| defparam Mantissa_Addition.exp = exp; |
| defparam Mantissa_Addition.man = man; |
| |
| //Post Normalization Module |
| wire output_interim_Post_Norm_Add_Guard; |
| wire output_interim_Post_Norm_Add_Round; |
| wire output_interim_Post_Norm_Add_Sticky; |
| wire [exp+1:0] output_interim_Post_Norm_Add_Exponent; |
| wire [man+1:0] output_interim_Post_Norm_Add_Mantissa; |
| FMADD_Post_Normalization_Add_Sub Post_Normalization_Add ( |
| .Post_Normalization_input_Mantissa ( output_interim_Mantissa_Addition_Mantissa ), |
| .Post_Normalization_input_exponent ( output_interim_Exponent_Mathcing_Exponent), |
| .Post_Normalization_input_Carry ( output_interim_Mantissa_Addition_Carry), |
| .Post_Normalization_input_Eff_sub ( output_interim_Exponent_Mathcing_Eff_sub ), |
| .Post_Normalization_input_Eff_add ( output_interim_Exponent_Mathcing_Eff_add), |
| .Post_Normalization_input_Guard ( output_interim_Exponent_Mathcing_Guard), |
| .Post_Normalization_input_Round ( output_interim_Exponent_Mathcing_Round), |
| .Post_Normalization_input_Sticky ( output_interim_Exponent_Mathcing_Sticky ), |
| .Post_Normalization_output_Guard ( output_interim_Post_Norm_Add_Guard), |
| .Post_Normalization_output_Round (output_interim_Post_Norm_Add_Round), |
| .Post_Normalization_output_Sticky ( output_interim_Post_Norm_Add_Sticky), |
| .Post_Normalization_output_Mantissa ( output_interim_Post_Norm_Add_Mantissa ), |
| .Post_Normalization_output_exponent ( output_interim_Post_Norm_Add_Exponent) |
| ); |
| defparam Post_Normalization_Add.std = std; |
| defparam Post_Normalization_Add.exp = exp; |
| defparam Post_Normalization_Add.man = man; |
| |
| //Rounding Mode Module |
| wire [exp:0] output_interim_Rounding_Block_Exp; |
| wire [man:0] output_interim_Rounding_Block_Mantissa; |
| wire output_interim_Rounding_Block_Sign; |
| wire [2:0] output_interim_Rounding_Block_S_flags; |
| wire [2:0] input_rounding_block_Add_frm; |
| |
| assign input_rounding_block_Add_frm = (|FMADD_SUBB_input_opcode[6:3] | (|FMADD_SUBB_input_opcode[1:0]) ) ? FMADD_SUBB_input_Frm : 3'b000; |
| |
| FMADD_Roudning_Block_Addition Rounding_Block_Add ( |
| .Rounding_Block_input_Mantissa (output_interim_Post_Norm_Add_Mantissa) , |
| .Rounding_Block_input_Exponent (output_interim_Post_Norm_Add_Exponent), |
| .Rounding_Block_input_Sign (output_interim_Exponent_Mathcing_Sign), |
| .Rounding_Block_input_Guard (output_interim_Post_Norm_Add_Guard), |
| .Rounding_Block_input_Round (output_interim_Post_Norm_Add_Round), |
| .Rounding_Block_input_Sticky (output_interim_Post_Norm_Add_Sticky), |
| .Rounding_Block_input_Frm (input_rounding_block_Add_frm), |
| .Rounding_Block_output_Exponent (output_interim_Rounding_Block_Exp), |
| .Rounding_Block_output_Sign ( output_interim_Rounding_Block_Sign), |
| .Rounding_Block_output_Mantissa( output_interim_Rounding_Block_Mantissa ), |
| .Rounding_Block_output_S_Flags (output_interim_Rounding_Block_S_flags) |
| ); |
| defparam Rounding_Block_Add.std = std; |
| defparam Rounding_Block_Add.exp = exp; |
| defparam Rounding_Block_Add.man = man; |
| |
| //Multiplication lane output ports |
| assign FMADD_SUBB_output_IEEE_FMUL = ( (~FMADD_SUBB_input_opcode[2]) | (~rst_l) ) ? { std+1 {1'b0} } : output_rounding_Block ; |
| assign FMADD_SUBB_output_S_Flags_FMUL = ( ( FMADD_SUBB_input_opcode[2] ) & (rst_l) ) ? output_interim_rounding_Block_S_Flag : 3'b000; |
| |
| //addition Lane output POrts |
| assign FMADD_SUBB_output_IEEE_FMADD = ( ((|FMADD_SUBB_input_opcode[1:0]) | (|FMADD_SUBB_input_opcode[6:3]) ) & (rst_l) ) ? { output_interim_Rounding_Block_Sign, output_interim_Rounding_Block_Exp ,output_interim_Rounding_Block_Mantissa } :{ std+1 {1'b0} } ; |
| assign FMADD_SUBB_output_S_Flags_FMADD = ( ( (|FMADD_SUBB_input_opcode[1:0]) | (|FMADD_SUBB_input_opcode[6:3]) ) & (rst_l) ) ? {output_interim_Rounding_Block_S_flags[1],output_interim_Rounding_Block_S_flags[2],output_interim_Rounding_Block_S_flags[0]} : 3'b00; |
| |
| |
| endmodule |
| |