| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- 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
|