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

Subversion Repositories sparc64soc

[/] [sparc64soc/] [trunk/] [T1-FPU/] [fpu_mul_frac_dp.v] - Blame information for rev 8

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

Line No. Rev Author Line
1 2 dmitryr
// ========== Copyright Header Begin ==========================================
2
// 
3
// OpenSPARC T1 Processor File: fpu_mul_frac_dp.v
4
// Copyright (c) 2006 Sun Microsystems, Inc.  All Rights Reserved.
5
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
6
// 
7
// The above named program is free software; you can redistribute it and/or
8
// modify it under the terms of the GNU General Public
9
// License version 2 as published by the Free Software Foundation.
10
// 
11
// The above named program is distributed in the hope that it will be 
12
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
// General Public License for more details.
15
// 
16
// You should have received a copy of the GNU General Public
17
// License along with this work; if not, write to the Free Software
18
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19
// 
20
// ========== Copyright Header End ============================================
21
///////////////////////////////////////////////////////////////////////////////
22
//
23
//      Multiply pipeline fraction datapath.
24
//
25
///////////////////////////////////////////////////////////////////////////////
26
 
27
 
28
module fpu_mul_frac_dp (
29
        inq_in1,
30
        inq_in2,
31
        m6stg_step,
32
        m2stg_frac1_dbl_norm,
33
        m2stg_frac1_dbl_dnrm,
34
        m2stg_frac1_sng_norm,
35
        m2stg_frac1_sng_dnrm,
36
        m2stg_frac1_inf,
37
        m1stg_snan_dbl_in1,
38
        m1stg_snan_sng_in1,
39
        m2stg_frac2_dbl_norm,
40
        m2stg_frac2_dbl_dnrm,
41
        m2stg_frac2_sng_norm,
42
        m2stg_frac2_sng_dnrm,
43
        m2stg_frac2_inf,
44
        m1stg_snan_dbl_in2,
45
        m1stg_snan_sng_in2,
46
        m1stg_inf_zero_in,
47
        m1stg_inf_zero_in_dbl,
48
        m1stg_dblop,
49
        m1stg_dblop_inv,
50
        m4stg_frac,
51
        m4stg_sh_cnt_in,
52
        m3bstg_ld0_inv,
53
        m4stg_left_shift_step,
54
        m4stg_right_shift_step,
55
        m5stg_fmuls,
56
        m5stg_fmulda,
57
        mul_frac_out_fracadd,
58
        mul_frac_out_frac,
59
        m5stg_in_of,
60
        m5stg_to_0,
61
        fmul_clken_l,
62
        rclk,
63
 
64
        m2stg_frac1_array_in,
65
        m2stg_frac2_array_in,
66
        m1stg_ld0_1,
67
        m1stg_ld0_2,
68
        m4stg_frac_105,
69
        m3stg_ld0_inv,
70
        m4stg_shl_54,
71
        m4stg_shl_55,
72
        m5stg_frac_32_0,
73
        m5stg_frac_dbl_nx,
74
        m5stg_frac_sng_nx,
75
        m5stg_frac_neq_0,
76
        m5stg_fracadd_cout,
77
        mul_frac_out,
78
 
79
        se,
80
        si,
81
        so
82
);
83
 
84
 
85
input [54:0]     inq_in1;                // request operand 1 to op pipes
86
input [54:0]     inq_in2;                // request operand 2 to op pipes
87
input           m6stg_step;             // advance the multiply pipe
88
input           m2stg_frac1_dbl_norm;   // select line to m2stg_frac1
89
input           m2stg_frac1_dbl_dnrm;   // select line to m2stg_frac1
90
input           m2stg_frac1_sng_norm;   // select line to m2stg_frac1
91
input           m2stg_frac1_sng_dnrm;   // select line to m2stg_frac1
92
input           m2stg_frac1_inf;        // select line to m2stg_frac1
93
input           m1stg_snan_dbl_in1;     // operand 1 is double signalling NaN
94
input           m1stg_snan_sng_in1;     // operand 1 is single signalling NaN
95
input           m2stg_frac2_dbl_norm;   // select line to m2stg_frac2
96
input           m2stg_frac2_dbl_dnrm;   // select line to m2stg_frac2
97
input           m2stg_frac2_sng_norm;   // select line to m2stg_frac2
98
input           m2stg_frac2_sng_dnrm;   // select line to m2stg_frac2
99
input           m2stg_frac2_inf;        // select line to m2stg_frac2
100
input           m1stg_snan_dbl_in2;     // operand 2 is double signalling NaN
101
input           m1stg_snan_sng_in2;     // operand 2 is single signalling NaN
102
input           m1stg_inf_zero_in;      // 1 operand is infinity; other is 0
103
input           m1stg_inf_zero_in_dbl;  // 1 opnd is infinity; other is 0- dbl
104
input           m1stg_dblop;            // double precision operation- mul 1 stg
105
input           m1stg_dblop_inv;        // single or int operation- mul 1 stg
106
input [105:0]    m4stg_frac;             // multiply array output
107
input [5:0]      m4stg_sh_cnt_in;        // multiply normalization shift count
108
input [6:0]      m3bstg_ld0_inv;         // leading 0's in multiply operands
109
input           m4stg_left_shift_step;  // select line to m5stg_frac
110
input           m4stg_right_shift_step; // select line to m5stg_frac
111
input           m5stg_fmuls;            // fmuls- multiply 5 stage
112
input           m5stg_fmulda;           // fmuld- multiply 5 stage
113
input           mul_frac_out_fracadd;   // select line to mul_frac_out
114
input           mul_frac_out_frac;      // select line to mul_frac_out
115
input           m5stg_in_of;            // multiply overflow- select exp out
116
input           m5stg_to_0;             // result to max finite on overflow
117
input           fmul_clken_l;           // multiply pipe clk enable - asserted low
118
input           rclk;           // global clock
119
 
120
output [52:0]    m2stg_frac1_array_in;   // multiply array input 1
121
output [52:0]    m2stg_frac2_array_in;   // multiply array input 2
122
output [5:0]     m1stg_ld0_1;            // denorm operand 1 leading 0's
123
output [5:0]     m1stg_ld0_2;            // denorm operand 2 leading 0's
124
output          m4stg_frac_105;         // multiply stage 4a fraction input[105]
125
output [6:0]     m3stg_ld0_inv;          // leading 0's in multiply operands
126
output          m4stg_shl_54;           // multiply shift left output bit[54]
127
output          m4stg_shl_55;           // multiply shift left output bit[55]
128
output [32:0]    m5stg_frac_32_0;        // multiply stage 5 fraction input
129
output          m5stg_frac_dbl_nx;      // double precision inexact result
130
output          m5stg_frac_sng_nx;      // single precision inexact result
131
output          m5stg_frac_neq_0;       // fraction input to mul 5 stage != 0
132
output          m5stg_fracadd_cout;     // fraction rounding adder carry out
133
output [51:0]    mul_frac_out;           // multiply fraction output
134
 
135
input           se;                     // scan_enable
136
input           si;                     // scan in
137
output          so;                     // scan out
138
 
139
 
140
wire [54:0]      mul_frac_in1;
141
wire [54:0]      mul_frac_in2;
142
wire [52:0]      m2stg_frac1_in;
143
wire [52:0]      m2stg_frac1_array_in;
144
wire [52:0]      m2stg_frac2_in;
145
wire [52:0]      m2stg_frac2_array_in;
146
wire [52:0]      m1stg_ld0_1_din;
147
wire [5:0]       m1stg_ld0_1;
148
wire [52:0]      m1stg_ld0_2_din;
149
wire [5:0]       m1stg_ld0_2;
150
wire            m4stg_frac_105;
151
wire [5:0]       m4stg_sh_cnt_5;
152
wire [5:0]       m4stg_sh_cnt_4;
153
wire [5:0]       m4stg_sh_cnt;
154
wire [6:0]       m3stg_ld0_inv;
155
wire [168:63]   m4stg_shl_tmp;
156
wire [55:0]      m4stg_shl;
157
wire            m4stg_shl_54;
158
wire            m4stg_shl_55;
159
 
160
// 2/18/03: Changed to 225:0 (for easier LEC matching plus closer to implementation)
161
// wire [219:0] m4stg_shr_tmp;
162
wire [168:0]     m4stg_shr_tmp;
163
 
164
wire [55:0]      m4stg_shr;
165
wire [54:0]      m5stg_frac_pre1_in;
166
wire [54:0]      m5stg_frac_pre1;
167
wire [54:0]      m5stg_frac_pre2_in;
168
wire [54:0]      m5stg_frac_pre2;
169
wire [54:0]      m5stg_frac_pre3_in;
170
wire [54:0]      m5stg_frac_pre3;
171
wire [54:0]      m5stg_frac_pre4_in;
172
wire [54:0]      m5stg_frac_pre4;
173
wire [54:33]    m5stg_frac_54_33;
174
wire [32:0]      m5stg_frac_32_0;
175
wire [54:3]     m5stg_fraca;
176
wire [54:0]      m5stg_fracb;
177
wire            m5stg_frac_dbl_nx;
178
wire            m5stg_frac_sng_nx;
179
wire            m5stg_frac_neq_0;
180
wire [52:0]      m5stg_fracadd_tmp;
181
wire            m5stg_fracadd_cout;
182
wire [51:0]      m5stg_fracadd;
183
wire [51:0]      mul_frac_out_in;
184
wire [51:0]      mul_frac_out;
185
wire [30:0] mstg_xtra_regs;
186
 
187
wire se_l;
188
 
189
assign se_l = ~se;
190
 
191
clken_buf  ckbuf_mul_frac_dp (
192
  .clk(clk),
193
  .rclk(rclk),
194
  .enb_l(fmul_clken_l),
195
  .tmb_l(se_l)
196
  );
197
 
198
///////////////////////////////////////////////////////////////////////////////
199
//
200
//      Multiply fraction inputs.
201
//
202
//      Multiply input stage.
203
//
204
///////////////////////////////////////////////////////////////////////////////
205
 
206
dffe_s #(55) i_mul_frac_in1 (
207
        .din    (inq_in1[54:0]),
208
        .en     (m6stg_step),
209
        .clk    (clk),
210
 
211
        .q      (mul_frac_in1[54:0]),
212
 
213
        .se     (se),
214
        .si     (),
215
        .so     ()
216
);
217
 
218
dffe_s #(55) i_mul_frac_in2 (
219
        .din    (inq_in2[54:0]),
220
        .en     (m6stg_step),
221
        .clk    (clk),
222
 
223
        .q      (mul_frac_in2[54:0]),
224
 
225
        .se     (se),
226
        .si     (),
227
        .so     ()
228
);
229
 
230
 
231
///////////////////////////////////////////////////////////////////////////////
232
//
233
//      Multiply normalization and special input injection.
234
//
235
//      Multiply stage 1.
236
//
237
///////////////////////////////////////////////////////////////////////////////
238
 
239
assign m2stg_frac1_in[52:0]= ({53{m2stg_frac1_dbl_norm}}
240
                            & {1'b1, (mul_frac_in1[51] || m1stg_snan_dbl_in1),
241
                                mul_frac_in1[50:0]})
242
                | ({53{m2stg_frac1_dbl_dnrm}}
243
                            & {mul_frac_in1[51:0], 1'b0})
244
                | ({53{m2stg_frac1_sng_norm}}
245
                            & {1'b1, (mul_frac_in1[54] || m1stg_snan_sng_in1),
246
                                mul_frac_in1[53:32], 29'b0})
247
                | ({53{m2stg_frac1_sng_dnrm}}
248
                            & {mul_frac_in1[54:32], 30'b0})
249
                | ({53{m2stg_frac1_inf}}
250
                            & 53'h10000000000000);
251
 
252
assign m2stg_frac1_array_in[52:0]= (~m2stg_frac1_in[52:0]);
253
 
254
assign m2stg_frac2_in[52:0]= ({53{m2stg_frac2_dbl_norm}}
255
                            & {1'b1, (mul_frac_in2[51] || m1stg_snan_dbl_in2),
256
                                mul_frac_in2[50:0]})
257
                | ({53{m2stg_frac2_dbl_dnrm}}
258
                            & {mul_frac_in2[51:0], 1'b0})
259
                | ({53{m2stg_frac2_sng_norm}}
260
                            & {1'b1, (mul_frac_in2[54] || m1stg_snan_sng_in2),
261
                                mul_frac_in2[53:32], 29'b0})
262
                | ({53{m2stg_frac2_sng_dnrm}}
263
                            & {mul_frac_in2[54:32], 30'b0})
264
                | ({53{m2stg_frac2_inf}}
265
                            & {1'b1, {23{m1stg_inf_zero_in}},
266
                                        {29{m1stg_inf_zero_in_dbl}}});
267
 
268
assign m2stg_frac2_array_in[52:0]= m2stg_frac2_in[52:0];
269
 
270
 
271
///////////////////////////////////////////////////////////////////////////////
272
//
273
//      Multiply leading 0 counts.
274
//
275
//      Multiply stage 1.
276
//
277
///////////////////////////////////////////////////////////////////////////////
278
 
279
assign m1stg_ld0_1_din[52:0]= ({53{m1stg_dblop_inv}}
280
                            & {mul_frac_in1[54:32], 30'b0})
281
                | ({53{m1stg_dblop}}
282
                            & {mul_frac_in1[51:0], 1'b0});
283
 
284
fpu_cnt_lead0_53b i_m1stg_ld0_1 (
285
        .din    (m1stg_ld0_1_din[52:0]),
286
 
287
        .lead0  (m1stg_ld0_1[5:0])
288
);
289
 
290
assign m1stg_ld0_2_din[52:0]= ({53{m1stg_dblop_inv}}
291
                            & {mul_frac_in2[54:32], 30'b0})
292
                | ({53{m1stg_dblop}}
293
                            & {mul_frac_in2[51:0], 1'b0});
294
 
295
fpu_cnt_lead0_53b i_m1stg_ld0_2 (
296
        .din    (m1stg_ld0_2_din[52:0]),
297
 
298
        .lead0  (m1stg_ld0_2[5:0])
299
);
300
 
301
 
302
///////////////////////////////////////////////////////////////////////////////
303
//
304
//      Multiply shifts for post-normalization/denormalization.
305
//
306
//      Multiply stage 4a.
307
//
308
///////////////////////////////////////////////////////////////////////////////
309
 
310
assign m4stg_frac_105= m4stg_frac[105];
311
 
312
dffe_s #(56) i_mstg_xtra_regs (
313
        .din    ({{6{m4stg_sh_cnt_in[5]}},
314
                        {6{m4stg_sh_cnt_in[4]}},
315
                        m4stg_sh_cnt_in[5:0],
316
                        m3bstg_ld0_inv[6:0],
317
                        31'h0000_0000}),
318
        .en     (m6stg_step),
319
        .clk    (clk),
320
 
321
        .q      ({m4stg_sh_cnt_5[5:0],
322
                        m4stg_sh_cnt_4[5:0],
323
                        m4stg_sh_cnt[5:0],
324
                        m3stg_ld0_inv[6:0],
325
                        mstg_xtra_regs[30:0]}),
326
        .se     (se),
327
        .si     (),
328
        .so     ()
329
);
330
 
331
//assign m4stg_shl_tmp[168:0]= {m4stg_frac[105:0], 63'b0}
332
//              << {m4stg_sh_cnt_5[0], m4stg_sh_cnt[4:0]};
333
 
334
  assign m4stg_shl_tmp[168:63]=  m4stg_frac[105:0]
335
                << {m4stg_sh_cnt_5[0], m4stg_sh_cnt[4:0]};
336
 
337
assign m4stg_shl[55:0]= {m4stg_shl_tmp[168:114], (|m4stg_shl_tmp[113:63])};
338
assign m4stg_shl_54= m4stg_shl[54];
339
 
340
assign m4stg_shl_55= m4stg_shl[55];
341
 
342
// 2/18/03: changed below to match implementation plus easier LEC
343
// assign m4stg_shr_tmp[219:0]= {57'b0, m4stg_frac[105:0], 57'b0} 
344
//                                              >> m4stg_sh_cnt[5:0];
345
// assign m4stg_shr[55:0]= {m4stg_shr_tmp[162:108], (|m4stg_shr_tmp[107:0])};
346
 
347
//assign m4stg_shr_tmp[225:0]= {57'b0, m4stg_frac[105:0], 63'b0} >> m4stg_sh_cnt[5:0];
348
  assign m4stg_shr_tmp[168:0]= {       m4stg_frac[105:0], 63'b0} >> m4stg_sh_cnt[5:0];
349
 
350
 
351
assign m4stg_shr[55:0]= {m4stg_shr_tmp[168:114], (|m4stg_shr_tmp[113:0])};
352
 
353
 
354
///////////////////////////////////////////////////////////////////////////////
355
//
356
//      Select post-normalization or denormalization result.
357
//
358
//      Multiply stage 4.
359
//
360
///////////////////////////////////////////////////////////////////////////////
361
 
362
// 2/18/03: Inverted the logic (nand instead of and) to reflect implementation and easier LEC
363
// assign m5stg_frac_pre1_in[54:0]= ({55{(m4stg_left_shift_step && m4stg_shl[55])}}
364
//           & m4stg_shl[54:0])
365
//     | ({55{(!m6stg_step)}}
366
//           & m5stg_fracb[54:0]);
367
 
368
assign m5stg_frac_pre1_in[54:0]= ~(({55{(m4stg_left_shift_step && m4stg_shl[55])}}
369
                            & m4stg_shl[54:0])
370
                | ({55{(!m6stg_step)}}
371
                            & m5stg_fracb[54:0]));
372
 
373
dff_s #(55) i_m5stg_frac_pre1 (
374
        .din    (m5stg_frac_pre1_in[54:0]),
375
        .clk    (clk),
376
 
377
        .q      (m5stg_frac_pre1[54:0]),
378
 
379
        .se     (se),
380
        .si     (),
381
        .so     ()
382
);
383
 
384
// 2/18/03: Inverted the logic (nand instead of and) to reflect implementation and easier LEC
385
// assign m5stg_frac_pre2_in[54:0]= ({55{(m4stg_left_shift_step
386
//           && (!m4stg_shl[55]))}}
387
//           & {m4stg_shl[53:0], 1'b0});
388
 
389
 
390
assign m5stg_frac_pre2_in[54:0]= ~({55{(m4stg_left_shift_step
391
                                        && (!m4stg_shl[55]))}}
392
                            & {m4stg_shl[53:0], 1'b0});
393
 
394
dff_s #(55) i_m5stg_frac_pre2 (
395
        .din    (m5stg_frac_pre2_in[54:0]),
396
        .clk    (clk),
397
 
398
        .q      (m5stg_frac_pre2[54:0]),
399
 
400
        .se     (se),
401
                .si     (),
402
        .so     ()
403
);
404
 
405
// 2/18/03: Inverted the logic (nand instead of and) to reflect implementation and easier LEC
406
// assign m5stg_frac_pre3_in[54:0]= ({55{(m4stg_right_shift_step
407
//           && m4stg_shr[55])}}
408
//           & m4stg_shr[54:0]);
409
 
410
assign m5stg_frac_pre3_in[54:0]= ~({55{(m4stg_right_shift_step
411
                                        && m4stg_shr[55])}}
412
                            & m4stg_shr[54:0]);
413
 
414
dff_s #(55) i_m5stg_frac_pre3 (
415
        .din    (m5stg_frac_pre3_in[54:0]),
416
        .clk    (clk),
417
 
418
        .q      (m5stg_frac_pre3[54:0]),
419
 
420
        .se     (se),
421
                .si     (),
422
        .so     ()
423
);
424
 
425
// 2/18/03: Inverted the logic (nand instead of and) to reflect implementation and easier LEC
426
// assign m5stg_frac_pre4_in[54:0]= ({55{(m4stg_right_shift_step
427
//           && (!m4stg_shr[55]))}}
428
//           & {m4stg_shr[53:0], 1'b0});
429
 
430
assign m5stg_frac_pre4_in[54:0]= ~({55{(m4stg_right_shift_step
431
                                        && (!m4stg_shr[55]))}}
432
                            & {m4stg_shr[53:0], 1'b0});
433
 
434
dff_s #(55) i_m5stg_frac_pre4 (
435
        .din    (m5stg_frac_pre4_in[54:0]),
436
        .clk    (clk),
437
 
438
        .q      (m5stg_frac_pre4[54:0]),
439
 
440
        .se     (se),
441
                .si     (),
442
        .so     ()
443
);
444
 
445
// 2/18/03: Inverted the logic (nand instead of or) to reflect implementation and easier LEC
446
// assign m5stg_frac[54:0]= (m5stg_frac_pre1[54:0]
447
//     | m5stg_frac_pre2[54:0]
448
//     | m5stg_frac_pre3[54:0]
449
//     | m5stg_frac_pre4[54:0]);
450
 
451
assign {m5stg_frac_54_33[54:33], m5stg_frac_32_0[32:0]} = ~(m5stg_frac_pre1[54:0]
452
                & m5stg_frac_pre2[54:0]
453
                & m5stg_frac_pre3[54:0]
454
                & m5stg_frac_pre4[54:0]);
455
 
456
 
457
assign m5stg_fraca[54:3]= {m5stg_frac_54_33[54:33], m5stg_frac_32_0[32:3]};
458
 
459
assign m5stg_fracb[54:0]= {m5stg_frac_54_33[54:33], m5stg_frac_32_0[32:0]};
460
 
461
 
462
///////////////////////////////////////////////////////////////////////////////
463
//
464
//      Multiply rounding.
465
//
466
//      Multiply stage 5.
467
//
468
///////////////////////////////////////////////////////////////////////////////
469
 
470
assign m5stg_frac_dbl_nx= (|m5stg_fracb[2:0]);
471
 
472
assign m5stg_frac_sng_nx= m5stg_frac_dbl_nx || (|m5stg_fracb[31:3]);
473
 
474
assign m5stg_frac_neq_0= m5stg_frac_sng_nx || (|m5stg_fracb[54:32]);
475
 
476
assign m5stg_fracadd_tmp[52:0]= {1'b0, m5stg_fraca[54:3]}
477
                        + {23'b0, m5stg_fmuls, 28'b0, m5stg_fmulda};
478
 
479
assign m5stg_fracadd_cout= m5stg_fracadd_tmp[52];
480
 
481
assign m5stg_fracadd[51:0]= m5stg_fracadd_tmp[51:0];
482
 
483
assign mul_frac_out_in[51:0]= ({52{mul_frac_out_fracadd}}
484
                            & m5stg_fracadd[51:0])
485
                | ({52{mul_frac_out_frac}}
486
                            & m5stg_fracb[54:3])
487
                | ({52{m5stg_in_of}}
488
                            & {52{m5stg_to_0}});
489
 
490
dffe_s #(52) i_mul_frac_out (
491
        .din    (mul_frac_out_in[51:0]),
492
        .en     (m6stg_step),
493
        .clk    (clk),
494
 
495
        .q      (mul_frac_out[51:0]),
496
 
497
        .se     (se),
498
        .si     (),
499
        .so     ()
500
);
501
 
502
endmodule
503
 
504
 

powered by: WebSVN 2.1.0

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