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

Subversion Repositories double_fpu

[/] [double_fpu/] [trunk/] [fpu_sub.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
 
36
`timescale 1ns / 100ps
37
 
38
 
39
module fpu_sub( clk, rst, enable, opa, opb, fpu_op, sign, diff_2, exponent_2);
40
input           clk;
41
input           rst;
42
input           enable;
43
input   [63:0]   opa, opb;
44
input   [2:0]    fpu_op;
45
output          sign;
46
output  [55:0]   diff_2;
47
output  [10:0]   exponent_2;
48
 
49
reg [6:0]        diff_shift;
50
reg [6:0]        diff_shift_2;
51
 
52
 
53
reg   [10:0] exponent_a;
54
reg   [10:0] exponent_b;
55
reg   [51:0] mantissa_a;
56
reg   [51:0] mantissa_b;
57
reg   expa_gt_expb;
58
reg   expa_et_expb;
59
reg   mana_gtet_manb;
60
reg   a_gtet_b;
61
reg   sign;
62
reg   [10:0] exponent_small;
63
reg   [10:0] exponent_large;
64
reg   [51:0] mantissa_small;
65
reg   [51:0] mantissa_large;
66
reg   small_is_denorm;
67
reg   large_is_denorm;
68
reg   large_norm_small_denorm;
69
reg   small_is_nonzero;
70
reg   [10:0] exponent_diff;
71
reg   [54:0] minuend;
72
reg   [54:0] subtrahend;
73
reg   [54:0] subtra_shift;
74
wire   subtra_shift_nonzero = |subtra_shift[54:0];
75
wire   subtra_fraction_enable = small_is_nonzero & !subtra_shift_nonzero;
76
wire   [54:0] subtra_shift_2 = { 54'b0, 1'b1 };
77
reg   [54:0] subtra_shift_3;
78
reg   [54:0] diff;
79
reg   diffshift_gt_exponent;
80
reg   diffshift_et_55; // when the difference = 0
81
reg   [54:0] diff_1;
82
reg   [10:0] exponent;
83
reg   [10:0] exponent_2;
84
wire   in_norm_out_denorm = (exponent_large > 0) & (exponent== 0);
85
reg   [55:0] diff_2;
86
 
87
 
88
always @(posedge clk)
89
        begin
90
                if (rst) begin
91
                exponent_a <= 0;
92
                exponent_b <= 0;
93
                mantissa_a <= 0;
94
                mantissa_b <= 0;
95
                expa_gt_expb <= 0;
96
                expa_et_expb <= 0;
97
                mana_gtet_manb <= 0;
98
                a_gtet_b <= 0;
99
                sign <= 0;
100
                exponent_small  <= 0;
101
                exponent_large  <= 0;
102
                mantissa_small  <= 0;
103
                mantissa_large  <= 0;
104
                small_is_denorm <= 0;
105
                large_is_denorm <= 0;
106
                large_norm_small_denorm <= 0;
107
                small_is_nonzero <= 0;
108
                exponent_diff <= 0;
109
                minuend <= 0;
110
                subtrahend <= 0;
111
                subtra_shift <= 0;
112
                subtra_shift_3 <= 0;
113
                diff_shift_2 <= 0;
114
                diff <= 0;
115
                diffshift_gt_exponent <= 0;
116
                diffshift_et_55 <= 0;
117
                diff_1 <= 0;
118
                exponent <= 0;
119
                exponent_2 <= 0;
120
                diff_2 <= 0;
121
                end
122
                else if (enable) begin
123
                exponent_a <= opa[62:52];
124
                exponent_b <= opb[62:52];
125
                mantissa_a <= opa[51:0];
126
                mantissa_b <= opb[51:0];
127
                expa_gt_expb <= exponent_a > exponent_b;
128
                expa_et_expb <= exponent_a == exponent_b;
129
                mana_gtet_manb <= mantissa_a >= mantissa_b;
130
                a_gtet_b <= expa_gt_expb | (expa_et_expb & mana_gtet_manb);
131
                sign <= a_gtet_b ? opa[63] :!opb[63] ^ (fpu_op == 3'b000);
132
                exponent_small  <= a_gtet_b ? exponent_b : exponent_a;
133
                exponent_large  <= a_gtet_b ? exponent_a : exponent_b;
134
                mantissa_small  <= a_gtet_b ? mantissa_b : mantissa_a;
135
                mantissa_large  <= a_gtet_b ? mantissa_a : mantissa_b;
136
                small_is_denorm <= !(exponent_small > 0);
137
                large_is_denorm <= !(exponent_large > 0);
138
                large_norm_small_denorm <= (small_is_denorm == 1 && large_is_denorm == 0);
139
                small_is_nonzero <= (exponent_small > 0) | |mantissa_small[51:0];
140
                exponent_diff <= exponent_large - exponent_small - large_norm_small_denorm;
141
                minuend <= { !large_is_denorm, mantissa_large, 2'b00 };
142
                subtrahend <= { !small_is_denorm, mantissa_small, 2'b00 };
143
                subtra_shift <= subtrahend >> exponent_diff;
144
                subtra_shift_3 <= subtra_fraction_enable ? subtra_shift_2 : subtra_shift;
145
                diff_shift_2 <= diff_shift;
146
                diff <= minuend - subtra_shift_3;
147
                diffshift_gt_exponent <= diff_shift_2 > exponent_large;
148
                diffshift_et_55 <= diff_shift_2 == 55;
149
                diff_1 <= diffshift_gt_exponent ? diff << exponent_large : diff << diff_shift_2;
150
                exponent <= diffshift_gt_exponent ? 0 : (exponent_large - diff_shift_2);
151
                exponent_2 <= diffshift_et_55 ? 0 : exponent;
152
                diff_2 <= in_norm_out_denorm ? { 1'b0, diff_1 >> 1} : {1'b0, diff_1};
153
 
154
                end
155
        end
156
 
157
 
158
always @(diff)
159
   casex(diff)
160 10 davidklun
    55'b1??????????????????????????????????????????????????????: diff_shift <=  0;
161
        55'b01?????????????????????????????????????????????????????: diff_shift <=  1;
162
        55'b001????????????????????????????????????????????????????: diff_shift <=  2;
163
        55'b0001???????????????????????????????????????????????????: diff_shift <=  3;
164
        55'b00001??????????????????????????????????????????????????: diff_shift <=  4;
165
        55'b000001?????????????????????????????????????????????????: diff_shift <=  5;
166
        55'b0000001????????????????????????????????????????????????: diff_shift <=  6;
167
        55'b00000001???????????????????????????????????????????????: diff_shift <=  7;
168
        55'b000000001??????????????????????????????????????????????: diff_shift <=  8;
169
        55'b0000000001?????????????????????????????????????????????: diff_shift <=  9;
170
        55'b00000000001????????????????????????????????????????????: diff_shift <=  10;
171
        55'b000000000001???????????????????????????????????????????: diff_shift <=  11;
172
        55'b0000000000001??????????????????????????????????????????: diff_shift <=  12;
173
        55'b00000000000001?????????????????????????????????????????: diff_shift <=  13;
174
        55'b000000000000001????????????????????????????????????????: diff_shift <=  14;
175
        55'b0000000000000001???????????????????????????????????????: diff_shift <=  15;
176
        55'b00000000000000001??????????????????????????????????????: diff_shift <=  16;
177
        55'b000000000000000001?????????????????????????????????????: diff_shift <=  17;
178
        55'b0000000000000000001????????????????????????????????????: diff_shift <=  18;
179
        55'b00000000000000000001???????????????????????????????????: diff_shift <=  19;
180
        55'b000000000000000000001??????????????????????????????????: diff_shift <=  20;
181
        55'b0000000000000000000001?????????????????????????????????: diff_shift <=  21;
182
        55'b00000000000000000000001????????????????????????????????: diff_shift <=  22;
183
        55'b000000000000000000000001???????????????????????????????: diff_shift <=  23;
184
        55'b0000000000000000000000001??????????????????????????????: diff_shift <=  24;
185
        55'b00000000000000000000000001?????????????????????????????: diff_shift <=  25;
186
        55'b000000000000000000000000001????????????????????????????: diff_shift <=  26;
187
        55'b0000000000000000000000000001???????????????????????????: diff_shift <=  27;
188
        55'b00000000000000000000000000001??????????????????????????: diff_shift <=  28;
189
        55'b000000000000000000000000000001?????????????????????????: diff_shift <=  29;
190
        55'b0000000000000000000000000000001????????????????????????: diff_shift <=  30;
191
        55'b00000000000000000000000000000001???????????????????????: diff_shift <=  31;
192
        55'b000000000000000000000000000000001??????????????????????: diff_shift <=  32;
193
        55'b0000000000000000000000000000000001?????????????????????: diff_shift <=  33;
194
        55'b00000000000000000000000000000000001????????????????????: diff_shift <=  34;
195
        55'b000000000000000000000000000000000001???????????????????: diff_shift <=  35;
196
        55'b0000000000000000000000000000000000001??????????????????: diff_shift <=  36;
197
        55'b00000000000000000000000000000000000001?????????????????: diff_shift <=  37;
198
        55'b000000000000000000000000000000000000001????????????????: diff_shift <=  38;
199
        55'b0000000000000000000000000000000000000001???????????????: diff_shift <=  39;
200
        55'b00000000000000000000000000000000000000001??????????????: diff_shift <=  40;
201
        55'b000000000000000000000000000000000000000001?????????????: diff_shift <=  41;
202
        55'b0000000000000000000000000000000000000000001????????????: diff_shift <=  42;
203
        55'b00000000000000000000000000000000000000000001???????????: diff_shift <=  43;
204
        55'b000000000000000000000000000000000000000000001??????????: diff_shift <=  44;
205
        55'b0000000000000000000000000000000000000000000001?????????: diff_shift <=  45;
206
        55'b00000000000000000000000000000000000000000000001????????: diff_shift <=  46;
207
        55'b000000000000000000000000000000000000000000000001???????: diff_shift <=  47;
208
        55'b0000000000000000000000000000000000000000000000001??????: diff_shift <=  48;
209
    55'b00000000000000000000000000000000000000000000000001?????: diff_shift <=  49;
210
        55'b000000000000000000000000000000000000000000000000001????: diff_shift <=  50;
211
        55'b0000000000000000000000000000000000000000000000000001???: diff_shift <=  51;
212
        55'b00000000000000000000000000000000000000000000000000001??: diff_shift <=  52;
213
        55'b000000000000000000000000000000000000000000000000000001?: diff_shift <=  53;
214
        55'b0000000000000000000000000000000000000000000000000000001: diff_shift <=  54;
215
        55'b0000000000000000000000000000000000000000000000000000000: diff_shift <=  55;
216 2 davidklun
        endcase
217
 
218
 
219
 
220
 
221
endmodule

powered by: WebSVN 2.1.0

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