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

Subversion Repositories fpu_double

[/] [fpu_double/] [trunk/] [fpu_add.vhd] - Blame information for rev 5

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
LIBRARY ieee;
36
USE ieee.std_logic_1164.all;
37
USE ieee.std_logic_arith.all;
38
use ieee.std_logic_unsigned.all;
39
use ieee.std_logic_misc.all;
40
 
41
 
42
ENTITY fpu_add IS
43
 
44
   PORT(
45
      clk : IN     std_logic;
46
      rst : IN     std_logic;
47
      enable  : IN     std_logic;
48
      opa : IN     std_logic_vector (63 DOWNTO 0);
49
      opb : IN     std_logic_vector (63 DOWNTO 0);
50
      sign : OUT    std_logic;
51
      sum_3 : OUT    std_logic_vector (55 DOWNTO 0);
52
      exponent_2 : OUT    std_logic_vector (10 DOWNTO 0)
53
   );
54
 
55
-- Declarations
56
 
57
END fpu_add;
58
 
59
architecture rtl of fpu_add is
60
 
61
 
62
signal   exponent_a : std_logic_vector(10 downto 0);
63
signal   exponent_b : std_logic_vector(10 downto 0);
64
signal   mantissa_a : std_logic_vector(51 downto 0);
65
signal   mantissa_b : std_logic_vector(51 downto 0);
66
signal   exponent_small : std_logic_vector(10 downto 0);
67
signal   exponent_large : std_logic_vector(10 downto 0);
68
signal   mantissa_small : std_logic_vector(51 downto 0);
69
signal   mantissa_large : std_logic_vector(51 downto 0);
70
signal   small_is_denorm : std_logic;
71
signal   large_is_denorm : std_logic;
72
signal   large_norm_small_denorm : std_logic_vector(10 downto 0);
73
signal   exponent_diff : std_logic_vector(10 downto 0);
74
signal   large_add : std_logic_vector(55 downto 0);
75
signal   small_add : std_logic_vector(55 downto 0);
76
signal   small_shift : std_logic_vector(55 downto 0);
77
signal   small_shift_nonzero : std_logic;
78
signal   small_is_nonzero : std_logic;
79
signal   small_fraction_enable : std_logic;
80
signal   small_shift_2 : std_logic_vector(55 downto 0);
81
signal   small_shift_3 : std_logic_vector(55 downto 0);
82
signal   sum : std_logic_vector(55 downto 0);
83
signal   sum_2 : std_logic_vector(55 downto 0);
84
signal   sum_overflow : std_logic;
85
signal   exponent : std_logic_vector(10 downto 0);
86
signal   sum_leading_one : std_logic;
87
signal   denorm_to_norm : std_logic;
88
 
89
signal   exp_diff_int : integer;
90
 
91
begin
92
 
93
small_shift_nonzero <= or_reduce(small_shift);
94
small_is_nonzero <= or_reduce(exponent_small) or or_reduce(mantissa_small(51 downto 0));
95
small_fraction_enable <= small_is_nonzero and not small_shift_nonzero;
96
small_shift_2 <= "00000000000000000000000000000000000000000000000000000001";
97
sum_overflow <= sum(55); -- sum[55] will be 0 if there was no carry from adding the 2 numbers
98
sum_leading_one <= sum_2(54); -- this is where the leading one resides, unless denorm
99
--exp_diff_int <= to_integer(exponent_diff);
100
 
101
process
102
        begin
103
        wait until clk'event and clk = '1';
104
                if (rst = '1') then
105
                        sign <= '0';
106
                        exponent_a <= (others =>'0');
107
                        exponent_b <= (others =>'0');
108
                        mantissa_a <= (others =>'0');
109
                        mantissa_b <= (others =>'0');
110
                        exponent_small  <= (others =>'0');
111
                        exponent_large  <= (others =>'0');
112
                        mantissa_small  <= (others =>'0');
113
                        mantissa_large  <= (others =>'0');
114
                        small_is_denorm <= '0';
115
                        large_is_denorm <= '0';
116
                        large_norm_small_denorm <= (others =>'0');
117
                        exponent_diff <= (others =>'0');
118
                        large_add <= (others =>'0');
119
                        small_add <= (others =>'0');
120
                        small_shift <= (others =>'0');
121
                        small_shift_3 <= (others =>'0');
122
                        sum <= (others =>'0');
123
                        sum_2 <= (others =>'0');
124
                        sum_3 <= (others =>'0');
125
                        exponent <= (others =>'0');
126
                        denorm_to_norm <= '0';
127
                        exponent_2 <= (others =>'0');
128
                elsif (enable = '1') then
129
                        sign <= opa(63);
130
                        exponent_a <= opa(62 downto 52);
131
                        exponent_b <= opb(62 downto 52);
132
                        mantissa_a <= opa(51 downto 0);
133
                        mantissa_b <= opb(51 downto 0);
134
                        if (exponent_a > exponent_b) then
135
                                exponent_small <= exponent_b;
136
                                exponent_large <= exponent_a;
137
                                mantissa_small <= mantissa_b;
138
                                mantissa_large <= mantissa_a;
139
                        else
140
                                exponent_small <= exponent_a;
141
                                exponent_large <= exponent_b;
142
                                mantissa_small <= mantissa_a;
143
                                mantissa_large <= mantissa_b;
144
                        end if;
145
                        if (exponent_small > 0) then
146
                                small_is_denorm <= '0';
147
                        else
148
                                small_is_denorm <= '1';
149
                        end if;
150
                        if (exponent_large > 0) then
151
                                large_is_denorm <= '0';
152
                        else
153
                                large_is_denorm <= '1';
154
                        end if;
155
                        if (small_is_denorm = '1' and large_is_denorm = '0') then
156
                                large_norm_small_denorm <= "00000000001";
157
                        else
158
                                large_norm_small_denorm <= "00000000000";
159
                        end if;
160
                        exponent_diff <= exponent_large - exponent_small - large_norm_small_denorm;
161
                        large_add <= '0' & not large_is_denorm & mantissa_large & "00";
162
                        small_add <= '0' & not small_is_denorm & mantissa_small & "00";
163
                        small_shift <= shr(small_add,  exponent_diff);
164
                        if (small_fraction_enable = '1') then
165
                                small_shift_3 <= small_shift_2;
166
                        else
167
                                small_shift_3 <= small_shift;
168
                        end if;
169
                        sum <= large_add + small_shift_3;
170
                        if (sum_overflow = '1') then
171
                                sum_2 <= shr(sum, conv_std_logic_vector('1', 56));
172
                        else
173
                                sum_2 <= sum;
174
                        end if;
175
                        sum_3 <= sum_2;
176
                        if (sum_overflow = '1') then
177
                                exponent <=  exponent_large + 1;
178
                        else
179
                                exponent <=  exponent_large;
180
                        end if;
181
                        denorm_to_norm <= sum_leading_one and large_is_denorm;
182
                        if (denorm_to_norm = '1') then
183
                                exponent_2 <= exponent + 1;
184
                        else
185
                                exponent_2 <= exponent;
186
                        end if;
187
                end if;
188
        end process;
189
 
190
 
191
end rtl;

powered by: WebSVN 2.1.0

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