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

Subversion Repositories double_fpu

[/] [double_fpu/] [trunk/] [fpu_add.v] - Blame information for rev 13

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 davidklun
/////////////////////////////////////////////////////////////////////
2
////                                                             ////
3
////  FPU                                                        ////
4
////  Floating Point Unit (Double precision)                     ////
5
////                                                             ////
6
////  Author: David Lundgren                                     ////
7
////          davidklun@gmail.com                                ////
8
////                                                             ////
9
/////////////////////////////////////////////////////////////////////
10
////                                                             ////
11
//// Copyright (C) 2009 David Lundgren                           ////
12
////                  davidklun@gmail.com                        ////
13
////                                                             ////
14
//// This source file may be used and distributed without        ////
15
//// restriction provided that this copyright statement is not   ////
16
//// removed from the file and that any derivative work contains ////
17
//// the original copyright notice and the associated disclaimer.////
18
////                                                             ////
19
////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
20
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
21
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
22
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
23
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
24
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
25
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
26
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
27
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
28
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
29
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
30
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
31
//// POSSIBILITY OF SUCH DAMAGE.                                 ////
32
////                                                             ////
33
/////////////////////////////////////////////////////////////////////
34
 
35
`timescale 1ns / 100ps
36
 
37
module fpu_add( clk, rst, enable, opa, opb, sign, sum_2, exponent_2);
38
input           clk;
39
input           rst;
40
input           enable;
41
input   [63:0]   opa, opb;
42
output          sign;
43
output  [55:0]   sum_2;
44
output  [10:0]   exponent_2;
45
 
46
reg   sign;
47
reg   [10:0] exponent_a;
48
reg   [10:0] exponent_b;
49
reg   [51:0] mantissa_a;
50
reg   [51:0] mantissa_b;
51
reg   expa_gt_expb;
52
reg   [10:0] exponent_small;
53
reg   [10:0] exponent_large;
54
reg   [51:0] mantissa_small;
55
reg   [51:0] mantissa_large;
56
reg   small_is_denorm;
57
reg   large_is_denorm;
58
reg   large_norm_small_denorm;
59
reg   [10:0] exponent_diff;
60
reg   [55:0] large_add;
61
reg   [55:0] small_add;
62
reg   [55:0] small_shift;
63
wire   small_shift_nonzero = |small_shift[55:0];
64
wire    small_is_nonzero = (exponent_small > 0) | |mantissa_small[51:0];
65
wire   small_fraction_enable = small_is_nonzero & !small_shift_nonzero;
66
wire   [55:0] small_shift_2 = { 55'b0, 1'b1 };
67
reg   [55:0] small_shift_3;
68
reg   [55:0] sum;
69
wire   sum_overflow = sum[55]; // sum[55] will be 0 if there was no carry from adding the 2 numbers
70
reg   [55:0] sum_2;
71
reg   [10:0] exponent;
72
wire   sum_leading_one = sum_2[54]; // this is where the leading one resides, unless denorm
73
reg   denorm_to_norm;
74
reg   [10:0] exponent_2;
75
 
76
always @(posedge clk)
77
        begin
78
                if (rst) begin
79
                        sign <= 0;
80
                        exponent_a <= 0;
81
                        exponent_b <= 0;
82
                        mantissa_a <= 0;
83
                        mantissa_b <= 0;
84
                        expa_gt_expb <= 0;
85
                        exponent_small  <= 0;
86
                        exponent_large  <= 0;
87
                        mantissa_small  <= 0;
88
                        mantissa_large  <= 0;
89
                        small_is_denorm <= 0;
90
                        large_is_denorm <= 0;
91
                        large_norm_small_denorm <= 0;
92
                        exponent_diff <= 0;
93
                        large_add <= 0;
94
                        small_add <= 0;
95
                        small_shift <= 0;
96
                        small_shift_3 <= 0;
97
                        sum <= 0;
98
                        sum_2 <= 0;
99
                        exponent <= 0;
100
                        denorm_to_norm <= 0;
101
                        exponent_2 <= 0;
102
                end
103
                else if (enable) begin
104
                        sign <= opa[63];
105
                        exponent_a <= opa[62:52];
106
                        exponent_b <= opb[62:52];
107
                        mantissa_a <= opa[51:0];
108
                        mantissa_b <= opb[51:0];
109
                        expa_gt_expb <= exponent_a > exponent_b;
110
                        exponent_small  <= expa_gt_expb ? exponent_b : exponent_a;
111
                        exponent_large  <= expa_gt_expb ? exponent_a : exponent_b;
112
                        mantissa_small  <= expa_gt_expb ? mantissa_b : mantissa_a;
113
                        mantissa_large  <= expa_gt_expb ? mantissa_a : mantissa_b;
114
                        small_is_denorm <= !(exponent_small > 0);
115
                        large_is_denorm <= !(exponent_large > 0);
116
                        large_norm_small_denorm <= (small_is_denorm && !large_is_denorm);
117
                        exponent_diff <= exponent_large - exponent_small - large_norm_small_denorm;
118
                        large_add <= { 1'b0, !large_is_denorm, mantissa_large, 2'b0 };
119
                        small_add <= { 1'b0, !small_is_denorm, mantissa_small, 2'b0 };
120
                        small_shift <= small_add >> exponent_diff;
121
                        small_shift_3 <= small_fraction_enable ? small_shift_2 : small_shift;
122
                        sum <= large_add + small_shift_3;
123
                        sum_2 <= sum_overflow ? sum >> 1 : sum;
124
                        exponent <= sum_overflow ? exponent_large + 1: exponent_large;
125
                        denorm_to_norm <= sum_leading_one & large_is_denorm;
126
                        exponent_2 <= denorm_to_norm ? exponent + 1 : exponent;
127
                end
128
        end
129
 
130
endmodule

powered by: WebSVN 2.1.0

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