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

Subversion Repositories double_fpu

[/] [double_fpu/] [trunk/] [pipeline/] [fpu_addsub.v] - Blame information for rev 6

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 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
// fpu_op, add = 0, subtract = 1
36
 
37
`timescale 1ns / 100ps
38
 
39
module fpu( clk, rst, enable, fpu_op, opa, opb, out, ready );
40
input           clk;
41
input           rst;
42
input           enable;
43
input           fpu_op;
44
input           [63:0]   opa, opb;
45
output          [63:0]   out;
46
output          ready;
47
 
48
 
49
reg     [63:0]   outfp, outfp_2, out;
50
reg     sign, sign_a, sign_b, fpu_op_1, fpu_op_2, fpu_op_3, fpu_op_4, fpu_op_final;
51
reg             fpuf_2, fpuf_3, fpuf_4, fpuf_5, fpuf_6, fpuf_7, fpuf_8, fpuf_9, fpuf_10;
52
reg             fpuf_11, fpuf_12, fpuf_13, fpuf_14, fpuf_15;
53
reg             sign_a2, sign_a3, sign_b2, sign_b3, sign_2, sign_3, sign_4, sign_5, sign_6;
54
reg             sign_7, sign_8, sign_9, sign_10, sign_11, sign_12;
55
reg     [10:0] exponent_a, exponent_b, expa_2, expb_2, expa_3, expb_3;
56
reg     [51:0] mantissa_a, mantissa_b, mana_2, mana_3, manb_2, manb_3;
57
reg             expa_et_inf, expb_et_inf, input_is_inf, in_inf2, in_inf3, in_inf4, in_inf5;
58
reg             in_inf6, in_inf7, in_inf8, in_inf9, in_inf10, in_inf11, in_inf12, in_inf13;
59
reg     in_inf14, in_inf15, expa_gt_expb, expa_et_expb, mana_gtet_manb, a_gtet_b;
60
reg     [10:0] exponent_small, exponent_large, expl_1, expl_2, expl_3, expl_4;
61
reg     [10:0] expl_5, expl_6, expl_7, expl_8, expl_9, expl_10, expl_11;
62
reg     [51:0] mantissa_small, mantissa_large;
63
reg     [51:0] mantissa_small_2, mantissa_large_2;
64
reg     [51:0] mantissa_small_3, mantissa_large_3;
65
reg             exp_small_et0, exp_large_et0, exp_small_et0_2, exp_large_et0_2;
66
reg     [10:0] exponent_diff, exponent_diff_2, exponent_diff_3, exponent_diff_4;
67
reg     [53:0] large_add, large_add_2, large_add_3, small_add;
68
reg             [53:0] small_shift, small_shift_2, small_shift_3, small_shift_4;
69
reg     [53:0] large_add_4, large_add_5;
70
reg     small_shift_nonzero;
71
reg             small_is_nonzero, small_is_nonzero_2, small_is_nonzero_3;
72
reg     small_fraction_enable;
73
wire    [53:0] small_shift_LSB = { 53'b0, 1'b1 };
74
reg     [53:0] sum, sum_2, sum_3, sum_4;
75
reg     sum_overflow;
76
reg     [10:0] exponent_add, exp_add2, exponent_sub, exponent_sub_2;
77
reg             [52:0] minuend, minuend_2, minuend_3, minuend_4, minuend_5, subtrahend;
78
reg             [52:0] subtra_shift, subtra_shift_2, subtra_shift_3, subtra_shift_4;
79
reg     subtra_shift_nonzero;
80
reg     subtra_fraction_enable;
81
wire    [52:0] subtra_shift_LSB = { 52'b0, 1'b1 };
82
reg     [5:0]    diff_shift, diff_shift_2;
83
reg             [52:0] diff, diff_2, diff_3, diff_4, diff_5;
84
reg             diffshift_gt_exponent, diffshift_et_53;
85
reg     ready, count_ready, count_ready_0;
86
reg             [4:0] count;
87
 
88
always @(posedge clk)
89
        begin
90
                if (rst) begin
91
                        sign <= 0; fpu_op_1 <= 0; fpu_op_final <= 0; fpu_op_2 <= 0;
92
                        fpu_op_3 <= 0; fpu_op_4 <= 0; fpuf_2 <= 0; fpuf_3 <= 0; fpuf_4 <= 0;
93
                        fpuf_5 <= 0; fpuf_6 <= 0; fpuf_7 <= 0; fpuf_8 <= 0; fpuf_9 <= 0;
94
                        fpuf_10 <= 0; fpuf_11 <= 0; fpuf_12 <= 0; fpuf_13 <= 0; fpuf_14 <= 0;
95
                        fpuf_15 <= 0; sign_a <= 0; sign_b <= 0;
96
                        sign_a2 <= 0; sign_b2 <= 0; sign_a3 <= 0; sign_b3 <= 0;
97
                        exponent_a <= 0; exponent_b <= 0; expa_2 <= 0; expa_3 <= 0;
98
                        expb_2 <= 0; expb_3 <= 0; mantissa_a <= 0; mantissa_b <= 0; mana_2 <= 0; mana_3 <= 0;
99
                        manb_2 <= 0; manb_3 <= 0; expa_et_inf <= 0; expb_et_inf <= 0;
100
                        input_is_inf <= 0; in_inf2 <= 0; in_inf3 <= 0; in_inf4 <= 0; in_inf5 <= 0;
101
                        in_inf6 <= 0; in_inf7 <= 0; in_inf8 <= 0; in_inf9 <= 0; in_inf10 <= 0;
102
                        in_inf11 <= 0; in_inf12 <= 0; in_inf13 <= 0; in_inf14 <= 0; in_inf15 <= 0;
103
                        expa_gt_expb <= 0; expa_et_expb <= 0; mana_gtet_manb <= 0;
104
                        a_gtet_b <= 0; sign <= 0; sign_2 <= 0; sign_3 <= 0; sign_4 <= 0; sign_5 <= 0;
105
                        sign_6 <= 0; sign_7 <= 0; sign_8 <= 0; sign_9 <= 0;
106
                        sign_10 <= 0; sign_11 <= 0; sign_12 <= 0;
107
                        exponent_small  <= 0; exponent_large  <= 0; expl_1 <= 0; expl_2 <= 0;
108
                        expl_3 <= 0; expl_4 <= 0; expl_5 <= 0; expl_6 <= 0; expl_7 <= 0;
109
                        expl_8 <= 0; expl_9 <= 0; expl_10 <= 0; expl_11 <= 0;
110
                        exp_small_et0 <= 0; exp_large_et0 <= 0;
111
                        exp_small_et0_2 <= 0; exp_large_et0_2 <= 0;
112
                        mantissa_small  <= 0; mantissa_large  <= 0;
113
                        mantissa_small_2 <= 0; mantissa_large_2 <= 0;
114
                        mantissa_small_3 <= 0; mantissa_large_3 <= 0;
115
                        exponent_diff <= 0; exponent_diff_2 <= 0; exponent_diff_3 <= 0;
116
                        exponent_diff_4 <= 0; large_add <= 0; large_add_2 <= 0;
117
                        large_add_3 <= 0; large_add_4 <= 0; large_add_5 <= 0; small_add <= 0;
118
                        small_shift <= 0; small_shift_2 <= 0; small_shift_3 <= 0;
119
                        small_shift_4 <= 0; small_shift_nonzero <= 0;
120
                        small_is_nonzero <= 0; small_is_nonzero_2 <= 0; small_is_nonzero_3 <= 0;
121
                        small_fraction_enable <= 0;
122
                        sum <= 0; sum_2 <= 0; sum_overflow <= 0; sum_3 <= 0; sum_4 <= 0;
123
                        exponent_add <= 0; exp_add2 <= 0;
124
                        minuend <= 0; minuend_2 <= 0; minuend_3 <= 0;
125
                        minuend_4 <= 0; minuend_5 <= 0; subtrahend <= 0;
126
                        subtra_shift <= 0; subtra_shift_2 <= 0; subtra_shift_3 <= 0;
127
                        subtra_shift_4 <= 0; subtra_shift_nonzero <= 0;
128
                        subtra_fraction_enable <= 0; diff_shift_2 <= 0; diff <= 0;
129
                        diffshift_gt_exponent <= 0; diffshift_et_53 <= 0; diff_2 <= 0;
130
                        diff_3 <= 0; diff_4 <= 0; diff_5 <= 0; exponent_sub <= 0;
131
                        exponent_sub_2 <= 0; outfp <= 0; outfp_2 <= 0;  out <= 0;
132
                end
133
                else if (enable) begin
134
                        fpu_op_1 <= fpu_op; fpu_op_final <= fpu_op_1 ^ (sign_a ^ sign_b);
135
                        fpuf_2 <= fpu_op_final; fpuf_3 <= fpuf_2; fpuf_4 <= fpuf_3;
136
                        fpuf_5 <= fpuf_4; fpuf_6 <= fpuf_5; fpuf_7 <= fpuf_6; fpuf_8 <= fpuf_7;
137
                        fpuf_9 <= fpuf_8; fpuf_10 <= fpuf_9; fpuf_11 <= fpuf_10; fpuf_12 <= fpuf_11;
138
                        fpuf_13 <= fpuf_12; fpuf_14 <= fpuf_13; fpuf_15 <= fpuf_14;
139
                        fpu_op_2 <= fpu_op_1; fpu_op_3 <= fpu_op_2; fpu_op_4 <= fpu_op_3;
140
                        sign_a <= opa[63]; sign_b <= opb[63]; sign_a2 <= sign_a;
141
                        sign_b2 <= sign_b; sign_a3 <= sign_a2; sign_b3 <= sign_b2;
142
                        exponent_a <= opa[62:52]; expa_2 <= exponent_a; expa_3 <= expa_2;
143
                        exponent_b <= opb[62:52]; expb_2 <= exponent_b; expb_3 <= expb_2;
144
                        mantissa_a <= opa[51:0]; mana_2 <= mantissa_a; mana_3 <= mana_2;
145
                        mantissa_b <= opb[51:0]; manb_2 <= mantissa_b; manb_3 <= manb_2;
146
                        expa_et_inf <= exponent_a == 2047;
147
                        expb_et_inf <= exponent_b == 2047;
148
                        input_is_inf <= expa_et_inf | expb_et_inf; in_inf2 <= input_is_inf;
149
                        in_inf3 <= in_inf2; in_inf4 <= in_inf3; in_inf5 <= in_inf4; in_inf6 <= in_inf5;
150
                        in_inf7 <= in_inf6; in_inf8 <= in_inf7; in_inf9 <= in_inf8; in_inf10 <= in_inf9;
151
                        in_inf11 <= in_inf10; in_inf12 <= in_inf11; in_inf13 <= in_inf12;
152
                        in_inf14 <= in_inf13; in_inf15 <= in_inf14;
153
                        expa_gt_expb <= exponent_a > exponent_b;
154
                        expa_et_expb <= exponent_a == exponent_b;
155
                        mana_gtet_manb <= mantissa_a >= mantissa_b;
156
                        a_gtet_b <= expa_gt_expb | (expa_et_expb & mana_gtet_manb);
157
                        sign <= a_gtet_b ? sign_a3 :!sign_b3 ^ (fpu_op_3 == 0);
158
                        sign_2 <= sign; sign_3 <= sign_2; sign_4 <= sign_3; sign_5 <= sign_4;
159
                        sign_6 <= sign_5; sign_7 <= sign_6; sign_8 <= sign_7; sign_9 <= sign_8;
160
                        sign_10 <= sign_9; sign_11 <= sign_10; sign_12 <= sign_11;
161
                        exponent_small  <= a_gtet_b ? expb_3 : expa_3;
162
                        exponent_large  <= a_gtet_b ? expa_3 : expb_3;
163
                        expl_2 <= exponent_large; expl_3 <= expl_2; expl_4 <= expl_3;
164
                        expl_5 <= expl_4; expl_6 <= expl_5; expl_7 <= expl_6; expl_8 <= expl_7;
165
                        expl_9 <= expl_8; expl_10 <= expl_9; expl_11 <= expl_10;
166
                        exp_small_et0 <= exponent_small == 0;
167
                        exp_large_et0 <= exponent_large == 0;
168
                        exp_small_et0_2 <= exp_small_et0;
169
                        exp_large_et0_2 <= exp_large_et0;
170
                        mantissa_small  <= a_gtet_b ? manb_3 : mana_3;
171
                        mantissa_large  <= a_gtet_b ? mana_3 : manb_3;
172
                        mantissa_small_2 <= mantissa_small;
173
                        mantissa_large_2 <= mantissa_large;
174
                        mantissa_small_3 <= exp_small_et0 ? 0 : mantissa_small_2;
175
                        mantissa_large_3 <= exp_large_et0 ? 0 : mantissa_large_2;
176
                        exponent_diff <= exponent_large - exponent_small;
177
                        exponent_diff_2 <= exponent_diff;
178
                        exponent_diff_3 <= exponent_diff_2;
179
                        exponent_diff_4 <= exponent_diff_3;
180
                        large_add <= { 1'b0, !exp_large_et0_2, mantissa_large_3};
181
                        large_add_2 <= large_add; large_add_3 <= large_add_2;
182
                        large_add_4 <= large_add_3; large_add_5 <= large_add_4;
183
                        small_add <= { 1'b0, !exp_small_et0_2, mantissa_small_3};
184
                        small_shift <= small_add >> exponent_diff_3;
185
                        small_shift_2 <= small_shift; small_shift_3 <= small_shift_2;
186
                        small_fraction_enable <= small_is_nonzero_3 & !small_shift_nonzero;
187
                        small_shift_4 <= small_fraction_enable ? small_shift_LSB : small_shift_3;
188
                        small_shift_nonzero <= |small_shift[53:0];
189
                        small_is_nonzero <= !exp_small_et0_2;
190
                        small_is_nonzero_2 <= small_is_nonzero; small_is_nonzero_3 <= small_is_nonzero_2;
191
                        sum <= large_add_5 + small_shift_4;
192
                        sum_overflow <= sum[53];
193
                        sum_2 <= sum;
194
                        sum_3 <= sum_overflow ? sum_2 >> 1 : sum_2;
195
                        sum_4 <= sum_3;
196
                        exponent_add <= sum_overflow ? expl_10 + 1: expl_10;
197
                        exp_add2 <= exponent_add;
198
                        minuend <= { !exp_large_et0_2, mantissa_large_3};
199
                        minuend_2 <= minuend; minuend_3 <= minuend_2;
200
                        minuend_4 <= minuend_3; minuend_5 <= minuend_4;
201
                        subtrahend <= { !exp_small_et0_2, mantissa_small_3};
202
                        subtra_shift <= subtrahend >> exponent_diff_3;
203
                        subtra_shift_2 <= subtra_shift;
204
                        subtra_shift_3 <= subtra_shift_2;
205
                        subtra_shift_nonzero <= |subtra_shift[52:0];
206
                        subtra_fraction_enable <= small_is_nonzero_3 & !subtra_shift_nonzero;
207
                        subtra_shift_4 <= subtra_fraction_enable ? subtra_shift_LSB : subtra_shift_3;
208
                        diff_shift_2 <= diff_shift;
209
                        diff <= minuend_5 - subtra_shift_4; diff_2 <= diff; diff_3 <= diff_2;
210
                        diffshift_gt_exponent <= diff_shift > expl_10;
211
                        diffshift_et_53 <= diff_shift_2 == 53;
212
                        diff_4 <= diffshift_gt_exponent ? diff_3 << expl_11 : diff_3 << diff_shift_2;
213
                        diff_5 <= diff_4;
214
                        exponent_sub <= diffshift_gt_exponent ? 0 : (expl_11 - diff_shift_2);
215
                        exponent_sub_2 <= diffshift_et_53 ? 0 : exponent_sub;
216
                        outfp <= {sign_12, exp_add2, sum_4[51:0]};
217
                        outfp_2 <= fpuf_15 ? {outfp[63], exponent_sub_2, diff_5[51:0]} : outfp;
218
                        out <= in_inf15 ? { outfp_2[63], 11'b11111111111, 52'b0 } : outfp_2;
219
                end
220
        end
221
 
222
 
223
 
224
always @(posedge clk)
225
   casex(diff)
226
    53'b1????????????????????????????????????????????????????: diff_shift <=  0;
227
        53'b01???????????????????????????????????????????????????: diff_shift <=  1;
228
        53'b001??????????????????????????????????????????????????: diff_shift <=  2;
229
        53'b0001?????????????????????????????????????????????????: diff_shift <=  3;
230
        53'b00001????????????????????????????????????????????????: diff_shift <=  4;
231
        53'b000001???????????????????????????????????????????????: diff_shift <=  5;
232
        53'b0000001??????????????????????????????????????????????: diff_shift <=  6;
233
        53'b00000001?????????????????????????????????????????????: diff_shift <=  7;
234
        53'b000000001????????????????????????????????????????????: diff_shift <=  8;
235
        53'b0000000001???????????????????????????????????????????: diff_shift <=  9;
236
        53'b00000000001??????????????????????????????????????????: diff_shift <=  10;
237
        53'b000000000001?????????????????????????????????????????: diff_shift <=  11;
238
        53'b0000000000001????????????????????????????????????????: diff_shift <=  12;
239
        53'b00000000000001???????????????????????????????????????: diff_shift <=  13;
240
        53'b000000000000001??????????????????????????????????????: diff_shift <=  14;
241
        53'b0000000000000001?????????????????????????????????????: diff_shift <=  15;
242
        53'b00000000000000001????????????????????????????????????: diff_shift <=  16;
243
        53'b000000000000000001???????????????????????????????????: diff_shift <=  17;
244
        53'b0000000000000000001??????????????????????????????????: diff_shift <=  18;
245
        53'b00000000000000000001?????????????????????????????????: diff_shift <=  19;
246
        53'b000000000000000000001????????????????????????????????: diff_shift <=  20;
247
        53'b0000000000000000000001???????????????????????????????: diff_shift <=  21;
248
        53'b00000000000000000000001??????????????????????????????: diff_shift <=  22;
249
        53'b000000000000000000000001?????????????????????????????: diff_shift <=  23;
250
        53'b0000000000000000000000001????????????????????????????: diff_shift <=  24;
251
        53'b00000000000000000000000001???????????????????????????: diff_shift <=  25;
252
        53'b000000000000000000000000001??????????????????????????: diff_shift <=  26;
253
        53'b0000000000000000000000000001?????????????????????????: diff_shift <=  27;
254
        53'b00000000000000000000000000001????????????????????????: diff_shift <=  28;
255
        53'b000000000000000000000000000001???????????????????????: diff_shift <=  29;
256
        53'b0000000000000000000000000000001??????????????????????: diff_shift <=  30;
257
        53'b00000000000000000000000000000001?????????????????????: diff_shift <=  31;
258
        53'b000000000000000000000000000000001????????????????????: diff_shift <=  32;
259
        53'b0000000000000000000000000000000001???????????????????: diff_shift <=  33;
260
        53'b00000000000000000000000000000000001??????????????????: diff_shift <=  34;
261
        53'b000000000000000000000000000000000001?????????????????: diff_shift <=  35;
262
        53'b0000000000000000000000000000000000001????????????????: diff_shift <=  36;
263
        53'b00000000000000000000000000000000000001???????????????: diff_shift <=  37;
264
        53'b000000000000000000000000000000000000001??????????????: diff_shift <=  38;
265
        53'b0000000000000000000000000000000000000001?????????????: diff_shift <=  39;
266
        53'b00000000000000000000000000000000000000001????????????: diff_shift <=  40;
267
        53'b000000000000000000000000000000000000000001???????????: diff_shift <=  41;
268
        53'b0000000000000000000000000000000000000000001??????????: diff_shift <=  42;
269
        53'b00000000000000000000000000000000000000000001?????????: diff_shift <=  43;
270
        53'b000000000000000000000000000000000000000000001????????: diff_shift <=  44;
271
        53'b0000000000000000000000000000000000000000000001???????: diff_shift <=  45;
272
        53'b00000000000000000000000000000000000000000000001??????: diff_shift <=  46;
273
        53'b000000000000000000000000000000000000000000000001?????: diff_shift <=  47;
274
        53'b0000000000000000000000000000000000000000000000001????: diff_shift <=  48;
275
    53'b00000000000000000000000000000000000000000000000001???: diff_shift <=  49;
276
        53'b000000000000000000000000000000000000000000000000001??: diff_shift <=  50;
277
        53'b0000000000000000000000000000000000000000000000000001?: diff_shift <=  51;
278
        53'b00000000000000000000000000000000000000000000000000001: diff_shift <=  52;
279
        53'b00000000000000000000000000000000000000000000000000000: diff_shift <=  53;
280
        endcase
281
 
282
 
283
always @(posedge clk)
284
begin
285
        if (rst) begin
286
                ready <= 0;
287
                count_ready_0 <= 0;
288
                count_ready  <= 0;
289
        end
290
        else if (enable) begin
291
                ready <= count_ready;
292
                count_ready_0 <= count == 15;
293
                count_ready <= count == 16;
294
        end
295
end
296
 
297
always @(posedge clk)
298
begin
299
        if (rst)
300
                count <= 0;
301
        else if (enable & !count_ready_0 & !count_ready)
302
                count <= count + 1;
303
end
304
 
305
endmodule

powered by: WebSVN 2.1.0

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