FpCustomMultiplier.v 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. module FpCustomMultiplier # (
  2. parameter ManWidth = 16,
  3. parameter ExpWidth = 6
  4. )
  5. (Rst_i,Clk_i,A_i,B_i,Nd_i,Result_o,ResultValid_o);
  6. localparam InOutWidth = 1+ExpWidth+ManWidth;
  7. input Rst_i;
  8. input Clk_i;
  9. input [InOutWidth-1:0] A_i;
  10. input [InOutWidth-1:0] B_i;
  11. input Nd_i;
  12. output [InOutWidth-1:0] Result_o;
  13. output ResultValid_o;
  14. localparam ExtManWidth = 2+ManWidth;
  15. localparam MultResultWidth = (ExtManWidth*2)-2;
  16. localparam ExpConst = (2**(ExpWidth-1))-1;
  17. reg expA_or;
  18. reg expB_or;
  19. reg signed [ExtManWidth-1:0] manAReg;
  20. reg signed [ExtManWidth-1:0] manBReg;
  21. reg [ExpWidth-1:0] expAReg;
  22. reg [ExpWidth-1:0] expBReg;
  23. always @(posedge Clk_i) begin
  24. expA_or <= |A_i[InOutWidth-2 -:ExpWidth]; //looking for zero exponents for mult operation
  25. expB_or <= |B_i[InOutWidth-2 -:ExpWidth];
  26. manAReg <= {2'b01,A_i[ManWidth-1 -:ManWidth]}; //add 0-sign and implied 1 to mantissa.
  27. manBReg <= {2'b01,B_i[ManWidth-1 -:ManWidth]};
  28. expAReg <= A_i[InOutWidth-2 -:ExpWidth]; //exp highlight
  29. expBReg <= B_i[InOutWidth-2 -:ExpWidth];
  30. end
  31. reg [ExpWidth:0] expAddProd;
  32. reg expZero;
  33. reg signed [MultResultWidth-1:0] manMultProd;
  34. always @(posedge Clk_i) begin
  35. manMultProd <= manAReg*manBReg; //man(C)=man(A)*man(B)
  36. expAddProd <= expAReg+expBReg-ExpConst; //exp(C)=exp(A)+exp(B)-ExpConst. ExpConst = 2^ExpWidth-1;
  37. expZero <= ~(expA_or&expB_or); //setting exp(C) = 0 when either A or B is zero or denormalized.
  38. end
  39. reg [ExpWidth-1:0] expCReg;
  40. reg expResultNegative;
  41. reg [ManWidth-1:0] manCReg;
  42. always @(posedge Clk_i) begin
  43. expResultNegative <= expAddProd[ExpWidth]; //if exponents are too small then their result will be negative
  44. if (Rst_i) begin
  45. expCReg <= {ExpWidth{1'b0}};
  46. end else if (expAddProd[ExpWidth]||expZero) begin
  47. expCReg <= {ExpWidth{1'b0}};
  48. end else begin
  49. expCReg <= expAddProd[ExpWidth-1:0]+manMultProd[MultResultWidth-1];
  50. end
  51. if (Rst_i) begin
  52. manCReg <= {ManWidth{1'b0}};
  53. end else if (expAddProd[ExpWidth]||expZero) begin
  54. manCReg <= {ManWidth{1'b0}};
  55. end else if (!manMultProd[MultResultWidth-1]) begin //normalize man(C) in accordance to MSB value
  56. manCReg <= manMultProd[MultResultWidth-3 -:ManWidth];
  57. end else begin
  58. manCReg <= manMultProd[MultResultWidth-2 -:ManWidth];
  59. end
  60. end
  61. reg [4:0] signCShReg;
  62. always @(posedge Clk_i) begin
  63. signCShReg <= {signCShReg[3:0], A_i[InOutWidth-1] ^ B_i[InOutWidth-1]};
  64. end
  65. reg [5:0] resValidShReg;
  66. always @(posedge Clk_i) begin
  67. resValidShReg <= {resValidShReg[4:0], Nd_i};
  68. end
  69. assign Result_o = {signCShReg[2], expCReg,manCReg};
  70. assign ResultValid_o = resValidShReg[2];
  71. endmodule