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

Subversion Repositories double_fpu

[/] [double_fpu/] [branches/] [avendor/] [fpu_mul.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
module fpu_mul( clk, rst, enable, opa, opb, sign, product_7, exponent_5);
39
input           clk;
40
input           rst;
41
input           enable;
42
input   [63:0]   opa, opb;
43
output          sign;
44
output  [55:0] product_7;
45
output  [11:0] exponent_5;
46
 
47
reg [5:0]        product_shift;
48
reg [5:0]        product_shift_2;
49
 
50
 
51
reg   sign;
52
reg   [51:0] mantissa_a;
53
reg   [51:0] mantissa_b;
54
reg   [10:0] exponent_a;
55
reg   [10:0] exponent_b;
56
reg             a_is_norm;
57
reg             b_is_norm;
58
reg             a_is_zero;
59
reg             b_is_zero;
60
reg             in_zero;
61
reg   [11:0] exponent_terms;
62
reg    exponent_gt_expoffset;
63
reg   [11:0] exponent_under;
64
reg   [11:0] exponent_1;
65
wire   [11:0] exponent = 0;
66
reg   [11:0] exponent_2;
67
reg   exponent_gt_prodshift;
68
reg   [11:0] exponent_3;
69
reg   [11:0] exponent_4;
70
reg  exponent_et_zero;
71
reg   [52:0] mul_a;
72
reg   [52:0] mul_b;
73
reg             [40:0] product_a;
74
reg             [40:0] product_b;
75
reg             [40:0] product_c;
76
reg             [25:0] product_d;
77
reg             [33:0] product_e;
78
reg             [33:0] product_f;
79
reg             [35:0] product_g;
80
reg             [28:0] product_h;
81
reg             [28:0] product_i;
82
reg             [30:0] product_j;
83
reg             [41:0] sum_0;
84
reg             [35:0] sum_1;
85
reg             [41:0] sum_2;
86
reg             [35:0] sum_3;
87
reg             [36:0] sum_4;
88
reg             [27:0] sum_5;
89
reg             [29:0] sum_6;
90
reg             [36:0] sum_7;
91
reg             [30:0] sum_8;
92
reg   [105:0] product;
93
reg   [105:0] product_1;
94
reg   [105:0] product_2;
95
reg   [105:0] product_3;
96
reg   [105:0] product_4;
97
reg   [105:0] product_5;
98
reg   [105:0] product_6;
99 10 davidklun
reg             product_lsb; // if there are any 1's in the remainder
100 2 davidklun
wire  [55:0] product_7 =  { 1'b0, product_6[105:52], product_lsb };
101
reg  [11:0] exponent_5;
102
 
103
always @(posedge clk)
104
begin
105
        if (rst) begin
106
                sign <= 0;
107
                mantissa_a <= 0;
108
                mantissa_b <= 0;
109
                exponent_a <= 0;
110
                exponent_b <= 0;
111
                a_is_norm <= 0;
112
                b_is_norm <= 0;
113
                a_is_zero <= 0;
114
                b_is_zero <= 0;
115
                in_zero <= 0;
116
                exponent_terms <= 0;
117
                exponent_gt_expoffset <= 0;
118
                exponent_under <= 0;
119
                exponent_1 <= 0;
120
                exponent_2 <= 0;
121
                exponent_gt_prodshift <= 0;
122
                exponent_3 <= 0;
123
                exponent_4 <= 0;
124
                exponent_et_zero <= 0;
125
                mul_a <= 0;
126
                mul_b <= 0;
127
                product_a <= 0;
128
                product_b <= 0;
129
                product_c <= 0;
130
                product_d <= 0;
131
                product_e <= 0;
132
                product_f <= 0;
133
                product_g <= 0;
134
                product_h <= 0;
135
                product_i <= 0;
136
                product_j <= 0;
137
                sum_0 <= 0;
138
                sum_1 <= 0;
139
                sum_2 <= 0;
140
                sum_3 <= 0;
141
                sum_4 <= 0;
142
                sum_5 <= 0;
143
                sum_6 <= 0;
144
                sum_7 <= 0;
145
                sum_8 <= 0;
146
                product <= 0;
147
                product_1 <= 0;
148
                product_2 <= 0;
149
                product_3 <= 0;
150
                product_4 <= 0;
151
                product_5 <= 0;
152
                product_6 <= 0;
153
                product_lsb <= 0;
154
                exponent_5 <= 0;
155
                product_shift_2 <= 0;
156
        end
157
        else if (enable) begin
158
                sign <= opa[63] ^ opb[63];
159
                mantissa_a <= opa[51:0];
160
                mantissa_b <= opb[51:0];
161
                exponent_a <= opa[62:52];
162
                exponent_b <= opb[62:52];
163
                a_is_norm <= |exponent_a;
164
                b_is_norm <= |exponent_b;
165 10 davidklun
                a_is_zero <= !(|opa[62:0]);
166
                b_is_zero <= !(|opb[62:0]);
167 2 davidklun
                in_zero <= a_is_zero | b_is_zero;
168
                exponent_terms <= exponent_a + exponent_b + !a_is_norm + !b_is_norm;
169
                exponent_gt_expoffset <= exponent_terms > 1021;
170
                exponent_under <= 1022 - exponent_terms;
171
                exponent_1 <= exponent_terms - 1022;
172
                exponent_2 <= exponent_gt_expoffset ? exponent_1 : exponent;
173
                exponent_gt_prodshift <= exponent_2 > product_shift_2;
174
                exponent_3 <= exponent_2 - product_shift;
175
                exponent_4 <= exponent_gt_prodshift ? exponent_3 : exponent;
176
                exponent_et_zero <= exponent_4 == 0;
177
                mul_a <= { a_is_norm, mantissa_a };
178
                mul_b <= { b_is_norm, mantissa_b };
179
                product_a <= mul_a[23:0] * mul_b[16:0];
180
                product_b <= mul_a[23:0] * mul_b[33:17];
181
                product_c <= mul_a[23:0] * mul_b[50:34];
182
                product_d <= mul_a[23:0] * mul_b[52:51];
183
                product_e <= mul_a[40:24] * mul_b[16:0];
184
                product_f <= mul_a[40:24] * mul_b[33:17];
185
                product_g <= mul_a[40:24] * mul_b[52:34];
186
                product_h <= mul_a[52:41] * mul_b[16:0];
187
                product_i <= mul_a[52:41] * mul_b[33:17];
188
                product_j <= mul_a[52:41] * mul_b[52:34];
189
                sum_0 <= product_a[40:17] + product_b;
190
                sum_1 <= sum_0[41:7] + product_e;
191
                sum_2 <= sum_1[35:10] + product_c;
192
                sum_3 <= sum_2[41:7] + product_h;
193
                sum_4 <= sum_3 + product_f;
194
                sum_5 <= sum_4[36:10] + product_d;
195
                sum_6 <= sum_5[27:7] + product_i;
196
                sum_7 <= sum_6 + product_g;
197
                sum_8 <= sum_7[36:17] + product_j;
198
                product <= { sum_8, sum_7[16:0], sum_5[6:0], sum_4[9:0], sum_2[6:0],
199
                                        sum_1[9:0], sum_0[6:0], product_a[16:0] };
200
                product_1 <= product >> exponent_under;
201
                product_2 <= exponent_gt_expoffset ? product : product_1;
202
                product_3 <= product_2 << product_shift_2;
203
                product_4 <= product_2 << exponent_2;
204
                product_5 <= exponent_gt_prodshift ? product_3  : product_4;
205
                product_6 <= exponent_et_zero ? product_5 >> 1 : product_5;
206
                product_lsb <= |product_6[51:0];
207
                exponent_5 <= in_zero ? 12'b0 : exponent_4;
208 10 davidklun
                product_shift_2 <= product_shift; // redundant register
209
                        // reduces fanout on product_shift
210 2 davidklun
        end
211
end
212
 
213
always @(product)
214
   casex(product)
215 10 davidklun
    106'b1?????????????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  0;
216
        106'b01????????????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  1;
217
        106'b001???????????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  2;
218
        106'b0001??????????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  3;
219
        106'b00001?????????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  4;
220
        106'b000001????????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  5;
221
        106'b0000001???????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  6;
222
        106'b00000001??????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  7;
223
        106'b000000001?????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  8;
224
        106'b0000000001????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  9;
225
        106'b00000000001???????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  10;
226
        106'b000000000001??????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  11;
227
        106'b0000000000001?????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  12;
228
        106'b00000000000001????????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  13;
229
        106'b000000000000001???????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  14;
230
        106'b0000000000000001??????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  15;
231
        106'b00000000000000001?????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  16;
232
        106'b000000000000000001????????????????????????????????????????????????????????????????????????????????????????: product_shift <=  17;
233
        106'b0000000000000000001???????????????????????????????????????????????????????????????????????????????????????: product_shift <=  18;
234
        106'b00000000000000000001??????????????????????????????????????????????????????????????????????????????????????: product_shift <=  19;
235
        106'b000000000000000000001?????????????????????????????????????????????????????????????????????????????????????: product_shift <=  20;
236
        106'b0000000000000000000001????????????????????????????????????????????????????????????????????????????????????: product_shift <=  21;
237
        106'b00000000000000000000001???????????????????????????????????????????????????????????????????????????????????: product_shift <=  22;
238
        106'b000000000000000000000001??????????????????????????????????????????????????????????????????????????????????: product_shift <=  23;
239
        106'b0000000000000000000000001?????????????????????????????????????????????????????????????????????????????????: product_shift <=  24;
240
        106'b00000000000000000000000001????????????????????????????????????????????????????????????????????????????????: product_shift <=  25;
241
        106'b000000000000000000000000001???????????????????????????????????????????????????????????????????????????????: product_shift <=  26;
242
        106'b0000000000000000000000000001??????????????????????????????????????????????????????????????????????????????: product_shift <=  27;
243
        106'b00000000000000000000000000001?????????????????????????????????????????????????????????????????????????????: product_shift <=  28;
244
        106'b000000000000000000000000000001????????????????????????????????????????????????????????????????????????????: product_shift <=  29;
245
        106'b0000000000000000000000000000001???????????????????????????????????????????????????????????????????????????: product_shift <=  30;
246
        106'b00000000000000000000000000000001??????????????????????????????????????????????????????????????????????????: product_shift <=  31;
247
        106'b000000000000000000000000000000001?????????????????????????????????????????????????????????????????????????: product_shift <=  32;
248
        106'b0000000000000000000000000000000001????????????????????????????????????????????????????????????????????????: product_shift <=  33;
249
        106'b00000000000000000000000000000000001???????????????????????????????????????????????????????????????????????: product_shift <=  34;
250
        106'b000000000000000000000000000000000001??????????????????????????????????????????????????????????????????????: product_shift <=  35;
251
        106'b0000000000000000000000000000000000001?????????????????????????????????????????????????????????????????????: product_shift <=  36;
252
        106'b00000000000000000000000000000000000001????????????????????????????????????????????????????????????????????: product_shift <=  37;
253
        106'b000000000000000000000000000000000000001???????????????????????????????????????????????????????????????????: product_shift <=  38;
254
        106'b0000000000000000000000000000000000000001??????????????????????????????????????????????????????????????????: product_shift <=  39;
255
        106'b00000000000000000000000000000000000000001?????????????????????????????????????????????????????????????????: product_shift <=  40;
256
        106'b000000000000000000000000000000000000000001????????????????????????????????????????????????????????????????: product_shift <=  41;
257
        106'b0000000000000000000000000000000000000000001???????????????????????????????????????????????????????????????: product_shift <=  42;
258
        106'b00000000000000000000000000000000000000000001??????????????????????????????????????????????????????????????: product_shift <=  43;
259
        106'b000000000000000000000000000000000000000000001?????????????????????????????????????????????????????????????: product_shift <=  44;
260
        106'b0000000000000000000000000000000000000000000001????????????????????????????????????????????????????????????: product_shift <=  45;
261
        106'b00000000000000000000000000000000000000000000001???????????????????????????????????????????????????????????: product_shift <=  46;
262
        106'b000000000000000000000000000000000000000000000001??????????????????????????????????????????????????????????: product_shift <=  47;
263
        106'b0000000000000000000000000000000000000000000000001?????????????????????????????????????????????????????????: product_shift <=  48;
264
    106'b00000000000000000000000000000000000000000000000001????????????????????????????????????????????????????????: product_shift <=  49;
265
        106'b000000000000000000000000000000000000000000000000001???????????????????????????????????????????????????????: product_shift <=  50;
266
        106'b0000000000000000000000000000000000000000000000000001??????????????????????????????????????????????????????: product_shift <=  51;
267
        106'b00000000000000000000000000000000000000000000000000001?????????????????????????????????????????????????????: product_shift <=  52;
268
        106'b000000000000000000000000000000000000000000000000000000????????????????????????????????????????????????????: product_shift <=  53;
269
          // It's not necessary to go past 53, because you will only get more than 53 zeros
270
          // when multiplying 2 denormalized numbers together, in which case you will underflow
271 2 davidklun
        endcase
272
 
273
endmodule

powered by: WebSVN 2.1.0

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