FpCustomMultiplier.v 2.6 KB

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