module FpCustomMultiplier # ( parameter ManWidth = 16, parameter ExpWidth = 6 ) ( Rst_i, Clk_i, A_i, B_i, Nd_i, Result_o, ResultValid_o ); localparam InOutWidth = 1+ExpWidth+ManWidth; input Rst_i; input Clk_i; input [InOutWidth-1:0] A_i; input [InOutWidth-1:0] B_i; input Nd_i; output [InOutWidth-1:0] Result_o; output ResultValid_o; localparam ExtManWidth = 2+ManWidth; localparam MultResultWidth = (ExtManWidth*2)-2; localparam ExpConst = (2**(ExpWidth-1))-1; reg expA_or; reg expB_or; reg signed [ExtManWidth-1:0] manAReg; reg signed [ExtManWidth-1:0] manBReg; reg [ExpWidth-1:0] expAReg; reg [ExpWidth-1:0] expBReg; always @(posedge Clk_i) begin expA_or <= |A_i[InOutWidth-2 -:ExpWidth]; //looking for zero exponents for mult operation expB_or <= |B_i[InOutWidth-2 -:ExpWidth]; manAReg <= {2'b01,A_i[ManWidth-1 -:ManWidth]}; //add 0-sign and implied 1 to mantissa. manBReg <= {2'b01,B_i[ManWidth-1 -:ManWidth]}; expAReg <= A_i[InOutWidth-2 -:ExpWidth]; //exp highlight expBReg <= B_i[InOutWidth-2 -:ExpWidth]; end reg [ExpWidth:0] expAddProd; reg expZero; reg signed [MultResultWidth-1:0] manMultProd; always @(posedge Clk_i) begin manMultProd <= manAReg*manBReg; //man(C)=man(A)*man(B) expAddProd <= expAReg+expBReg-ExpConst; //exp(C)=exp(A)+exp(B)-ExpConst. ExpConst = 2^ExpWidth-1; expZero <= ~(expA_or&expB_or); //setting exp(C) = 0 when either A or B is zero or denormalized. end reg [ExpWidth-1:0] expCReg; reg expResultNegative; reg [ManWidth-1:0] manCReg; always @(posedge Clk_i) begin expResultNegative <= expAddProd[ExpWidth]; //if exponents are too small then their result will be negative if (Rst_i) begin expCReg <= {ExpWidth{1'b0}}; end else if (expAddProd[ExpWidth]||expZero) begin expCReg <= {ExpWidth{1'b0}}; end else begin expCReg <= expAddProd[ExpWidth-1:0]+manMultProd[MultResultWidth-1]; end if (Rst_i) begin manCReg <= {ManWidth{1'b0}}; end else if (expAddProd[ExpWidth]||expZero) begin manCReg <= {ManWidth{1'b0}}; end else if (!manMultProd[MultResultWidth-1]) begin //normalize man(C) in accordance to MSB value manCReg <= manMultProd[MultResultWidth-3 -:ManWidth]; end else begin manCReg <= manMultProd[MultResultWidth-2 -:ManWidth]; end end reg [4:0] signCShReg; always @(posedge Clk_i) begin signCShReg <= {signCShReg[3:0], A_i[InOutWidth-1] ^ B_i[InOutWidth-1]}; end reg [5:0] resValidShReg; always @(posedge Clk_i) begin resValidShReg <= {resValidShReg[4:0], Nd_i}; end assign Result_o = {signCShReg[2], expCReg,manCReg}; assign ResultValid_o = resValidShReg[2]; endmodule