OpenCores
URL https://opencores.org/ocsvn/double_fpu/double_fpu/trunk

Subversion Repositories double_fpu

[/] [double_fpu/] [trunk/] [fpu_mul.v] - Diff between revs 11 and 13

Only display areas with differences | Details | Blame | View Log

Rev 11 Rev 13
 
/////////////////////////////////////////////////////////////////////
 
////                                                             ////
 
////  FPU                                                        ////
 
////  Floating Point Unit (Double precision)                     ////
 
////                                                             ////
 
////  Author: David Lundgren                                     ////
 
////          davidklun@gmail.com                                ////
 
////                                                             ////
 
/////////////////////////////////////////////////////////////////////
 
////                                                             ////
 
//// Copyright (C) 2009 David Lundgren                           ////
 
////                  davidklun@gmail.com                        ////
 
////                                                             ////
 
//// This source file may be used and distributed without        ////
 
//// restriction provided that this copyright statement is not   ////
 
//// removed from the file and that any derivative work contains ////
 
//// the original copyright notice and the associated disclaimer.////
 
////                                                             ////
 
////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
 
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
 
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
 
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
 
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
 
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
 
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
 
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
 
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
 
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
 
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
 
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
 
//// POSSIBILITY OF SUCH DAMAGE.                                 ////
 
////                                                             ////
 
/////////////////////////////////////////////////////////////////////
 
 
 
 
 
`timescale 1ns / 100ps
 
 
 
module fpu_mul( clk, rst, enable, opa, opb, sign, product_7, exponent_5);
 
input           clk;
 
input           rst;
 
input           enable;
 
input   [63:0]   opa, opb;
 
output          sign;
 
output  [55:0] product_7;
 
output  [11:0] exponent_5;
 
 
 
reg [5:0]        product_shift;
 
reg [5:0]        product_shift_2;
 
 
 
 
 
reg   sign;
 
reg   [51:0] mantissa_a;
 
reg   [51:0] mantissa_b;
 
reg   [10:0] exponent_a;
 
reg   [10:0] exponent_b;
 
reg             a_is_norm;
 
reg             b_is_norm;
 
reg             a_is_zero;
 
reg             b_is_zero;
 
reg             in_zero;
 
reg   [11:0] exponent_terms;
 
reg    exponent_gt_expoffset;
 
reg   [11:0] exponent_under;
 
reg   [11:0] exponent_1;
 
wire   [11:0] exponent = 0;
 
reg   [11:0] exponent_2;
 
reg   exponent_gt_prodshift;
 
reg   [11:0] exponent_3;
 
reg   [11:0] exponent_4;
 
reg  exponent_et_zero;
 
reg   [52:0] mul_a;
 
reg   [52:0] mul_b;
 
reg             [40:0] product_a;
 
reg             [40:0] product_b;
 
reg             [40:0] product_c;
 
reg             [25:0] product_d;
 
reg             [33:0] product_e;
 
reg             [33:0] product_f;
 
reg             [35:0] product_g;
 
reg             [28:0] product_h;
 
reg             [28:0] product_i;
 
reg             [30:0] product_j;
 
reg             [41:0] sum_0;
 
reg             [35:0] sum_1;
 
reg             [41:0] sum_2;
 
reg             [35:0] sum_3;
 
reg             [36:0] sum_4;
 
reg             [27:0] sum_5;
 
reg             [29:0] sum_6;
 
reg             [36:0] sum_7;
 
reg             [30:0] sum_8;
 
reg   [105:0] product;
 
reg   [105:0] product_1;
 
reg   [105:0] product_2;
 
reg   [105:0] product_3;
 
reg   [105:0] product_4;
 
reg   [105:0] product_5;
 
reg   [105:0] product_6;
 
reg             product_lsb; // if there are any 1's in the remainder
 
wire  [55:0] product_7 =  { 1'b0, product_6[105:52], product_lsb };
 
reg  [11:0] exponent_5;
 
 
 
always @(posedge clk)
 
begin
 
        if (rst) begin
 
                sign <= 0;
 
                mantissa_a <= 0;
 
                mantissa_b <= 0;
 
                exponent_a <= 0;
 
                exponent_b <= 0;
 
                a_is_norm <= 0;
 
                b_is_norm <= 0;
 
                a_is_zero <= 0;
 
                b_is_zero <= 0;
 
                in_zero <= 0;
 
                exponent_terms <= 0;
 
                exponent_gt_expoffset <= 0;
 
                exponent_under <= 0;
 
                exponent_1 <= 0;
 
                exponent_2 <= 0;
 
                exponent_gt_prodshift <= 0;
 
                exponent_3 <= 0;
 
                exponent_4 <= 0;
 
                exponent_et_zero <= 0;
 
                mul_a <= 0;
 
                mul_b <= 0;
 
                product_a <= 0;
 
                product_b <= 0;
 
                product_c <= 0;
 
                product_d <= 0;
 
                product_e <= 0;
 
                product_f <= 0;
 
                product_g <= 0;
 
                product_h <= 0;
 
                product_i <= 0;
 
                product_j <= 0;
 
                sum_0 <= 0;
 
                sum_1 <= 0;
 
                sum_2 <= 0;
 
                sum_3 <= 0;
 
                sum_4 <= 0;
 
                sum_5 <= 0;
 
                sum_6 <= 0;
 
                sum_7 <= 0;
 
                sum_8 <= 0;
 
                product <= 0;
 
                product_1 <= 0;
 
                product_2 <= 0;
 
                product_3 <= 0;
 
                product_4 <= 0;
 
                product_5 <= 0;
 
                product_6 <= 0;
 
                product_lsb <= 0;
 
                exponent_5 <= 0;
 
                product_shift_2 <= 0;
 
        end
 
        else if (enable) begin
 
                sign <= opa[63] ^ opb[63];
 
                mantissa_a <= opa[51:0];
 
                mantissa_b <= opb[51:0];
 
                exponent_a <= opa[62:52];
 
                exponent_b <= opb[62:52];
 
                a_is_norm <= |exponent_a;
 
                b_is_norm <= |exponent_b;
 
                a_is_zero <= !(|opa[62:0]);
 
                b_is_zero <= !(|opb[62:0]);
 
                in_zero <= a_is_zero | b_is_zero;
 
                exponent_terms <= exponent_a + exponent_b + !a_is_norm + !b_is_norm;
 
                exponent_gt_expoffset <= exponent_terms > 1021;
 
                exponent_under <= 1022 - exponent_terms;
 
                exponent_1 <= exponent_terms - 1022;
 
                exponent_2 <= exponent_gt_expoffset ? exponent_1 : exponent;
 
                exponent_gt_prodshift <= exponent_2 > product_shift_2;
 
                exponent_3 <= exponent_2 - product_shift;
 
                exponent_4 <= exponent_gt_prodshift ? exponent_3 : exponent;
 
                exponent_et_zero <= exponent_4 == 0;
 
                mul_a <= { a_is_norm, mantissa_a };
 
                mul_b <= { b_is_norm, mantissa_b };
 
                product_a <= mul_a[23:0] * mul_b[16:0];
 
                product_b <= mul_a[23:0] * mul_b[33:17];
 
                product_c <= mul_a[23:0] * mul_b[50:34];
 
                product_d <= mul_a[23:0] * mul_b[52:51];
 
                product_e <= mul_a[40:24] * mul_b[16:0];
 
                product_f <= mul_a[40:24] * mul_b[33:17];
 
                product_g <= mul_a[40:24] * mul_b[52:34];
 
                product_h <= mul_a[52:41] * mul_b[16:0];
 
                product_i <= mul_a[52:41] * mul_b[33:17];
 
                product_j <= mul_a[52:41] * mul_b[52:34];
 
                sum_0 <= product_a[40:17] + product_b;
 
                sum_1 <= sum_0[41:7] + product_e;
 
                sum_2 <= sum_1[35:10] + product_c;
 
                sum_3 <= sum_2[41:7] + product_h;
 
                sum_4 <= sum_3 + product_f;
 
                sum_5 <= sum_4[36:10] + product_d;
 
                sum_6 <= sum_5[27:7] + product_i;
 
                sum_7 <= sum_6 + product_g;
 
                sum_8 <= sum_7[36:17] + product_j;
 
                product <= { sum_8, sum_7[16:0], sum_5[6:0], sum_4[9:0], sum_2[6:0],
 
                                        sum_1[9:0], sum_0[6:0], product_a[16:0] };
 
                product_1 <= product >> exponent_under;
 
                product_2 <= exponent_gt_expoffset ? product : product_1;
 
                product_3 <= product_2 << product_shift_2;
 
                product_4 <= product_2 << exponent_2;
 
                product_5 <= exponent_gt_prodshift ? product_3  : product_4;
 
                product_6 <= exponent_et_zero ? product_5 >> 1 : product_5;
 
                product_lsb <= |product_6[51:0];
 
                exponent_5 <= in_zero ? 12'b0 : exponent_4;
 
                product_shift_2 <= product_shift; // redundant register
 
                        // reduces fanout on product_shift
 
        end
 
end
 
 
 
always @(product)
 
   casex(product)
 
    106'b1?????????????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  0;
 
        106'b01????????????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  1;
 
        106'b001???????????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  2;
 
        106'b0001??????????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  3;
 
        106'b00001?????????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  4;
 
        106'b000001????????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  5;
 
        106'b0000001???????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  6;
 
        106'b00000001??????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  7;
 
        106'b000000001?????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  8;
 
        106'b0000000001????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  9;
 
        106'b00000000001???????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  10;
 
        106'b000000000001??????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  11;
 
        106'b0000000000001?????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  12;
 
        106'b00000000000001????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  13;
 
        106'b000000000000001???????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  14;
 
        106'b0000000000000001??????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  15;
 
        106'b00000000000000001?????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  16;
 
        106'b000000000000000001????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  17;
 
        106'b0000000000000000001???????????????????????????????????????????????????????????????????????????????????????: product_shift <=  18;
 
        106'b00000000000000000001??????????????????????????????????????????????????????????????????????????????????????: product_shift <=  19;
 
        106'b000000000000000000001?????????????????????????????????????????????????????????????????????????????????????: product_shift <=  20;
 
        106'b0000000000000000000001????????????????????????????????????????????????????????????????????????????????????: product_shift <=  21;
 
        106'b00000000000000000000001???????????????????????????????????????????????????????????????????????????????????: product_shift <=  22;
 
        106'b000000000000000000000001??????????????????????????????????????????????????????????????????????????????????: product_shift <=  23;
 
        106'b0000000000000000000000001?????????????????????????????????????????????????????????????????????????????????: product_shift <=  24;
 
        106'b00000000000000000000000001????????????????????????????????????????????????????????????????????????????????: product_shift <=  25;
 
        106'b000000000000000000000000001???????????????????????????????????????????????????????????????????????????????: product_shift <=  26;
 
        106'b0000000000000000000000000001??????????????????????????????????????????????????????????????????????????????: product_shift <=  27;
 
        106'b00000000000000000000000000001?????????????????????????????????????????????????????????????????????????????: product_shift <=  28;
 
        106'b000000000000000000000000000001????????????????????????????????????????????????????????????????????????????: product_shift <=  29;
 
        106'b0000000000000000000000000000001???????????????????????????????????????????????????????????????????????????: product_shift <=  30;
 
        106'b00000000000000000000000000000001??????????????????????????????????????????????????????????????????????????: product_shift <=  31;
 
        106'b000000000000000000000000000000001?????????????????????????????????????????????????????????????????????????: product_shift <=  32;
 
        106'b0000000000000000000000000000000001????????????????????????????????????????????????????????????????????????: product_shift <=  33;
 
        106'b00000000000000000000000000000000001???????????????????????????????????????????????????????????????????????: product_shift <=  34;
 
        106'b000000000000000000000000000000000001??????????????????????????????????????????????????????????????????????: product_shift <=  35;
 
        106'b0000000000000000000000000000000000001?????????????????????????????????????????????????????????????????????: product_shift <=  36;
 
        106'b00000000000000000000000000000000000001????????????????????????????????????????????????????????????????????: product_shift <=  37;
 
        106'b000000000000000000000000000000000000001???????????????????????????????????????????????????????????????????: product_shift <=  38;
 
        106'b0000000000000000000000000000000000000001??????????????????????????????????????????????????????????????????: product_shift <=  39;
 
        106'b00000000000000000000000000000000000000001?????????????????????????????????????????????????????????????????: product_shift <=  40;
 
        106'b000000000000000000000000000000000000000001????????????????????????????????????????????????????????????????: product_shift <=  41;
 
        106'b0000000000000000000000000000000000000000001???????????????????????????????????????????????????????????????: product_shift <=  42;
 
        106'b00000000000000000000000000000000000000000001??????????????????????????????????????????????????????????????: product_shift <=  43;
 
        106'b000000000000000000000000000000000000000000001?????????????????????????????????????????????????????????????: product_shift <=  44;
 
        106'b0000000000000000000000000000000000000000000001????????????????????????????????????????????????????????????: product_shift <=  45;
 
        106'b00000000000000000000000000000000000000000000001???????????????????????????????????????????????????????????: product_shift <=  46;
 
        106'b000000000000000000000000000000000000000000000001??????????????????????????????????????????????????????????: product_shift <=  47;
 
        106'b0000000000000000000000000000000000000000000000001?????????????????????????????????????????????????????????: product_shift <=  48;
 
    106'b00000000000000000000000000000000000000000000000001????????????????????????????????????????????????????????: product_shift <=  49;
 
        106'b000000000000000000000000000000000000000000000000001???????????????????????????????????????????????????????: product_shift <=  50;
 
        106'b0000000000000000000000000000000000000000000000000001??????????????????????????????????????????????????????: product_shift <=  51;
 
        106'b00000000000000000000000000000000000000000000000000001?????????????????????????????????????????????????????: product_shift <=  52;
 
        106'b000000000000000000000000000000000000000000000000000000????????????????????????????????????????????????????: product_shift <=  53;
 
          // It's not necessary to go past 53, because you will only get more than 53 zeros
 
          // when multiplying 2 denormalized numbers together, in which case you will underflow
 
        endcase
 
 
 
endmodule
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.