source: XOpenSparcT1/trunk/T1-FPU/fpu_mul_frac_dp.v @ 6

Revision 6, 14.7 KB checked in by pntsvt00, 13 years ago (diff)

versione iniziale opensparc

Line 
1// ========== 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
28module 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
85input [54:0]    inq_in1;                // request operand 1 to op pipes
86input [54:0]    inq_in2;                // request operand 2 to op pipes
87input           m6stg_step;             // advance the multiply pipe
88input           m2stg_frac1_dbl_norm;   // select line to m2stg_frac1
89input           m2stg_frac1_dbl_dnrm;   // select line to m2stg_frac1
90input           m2stg_frac1_sng_norm;   // select line to m2stg_frac1
91input           m2stg_frac1_sng_dnrm;   // select line to m2stg_frac1
92input           m2stg_frac1_inf;        // select line to m2stg_frac1
93input           m1stg_snan_dbl_in1;     // operand 1 is double signalling NaN
94input           m1stg_snan_sng_in1;     // operand 1 is single signalling NaN
95input           m2stg_frac2_dbl_norm;   // select line to m2stg_frac2
96input           m2stg_frac2_dbl_dnrm;   // select line to m2stg_frac2
97input           m2stg_frac2_sng_norm;   // select line to m2stg_frac2
98input           m2stg_frac2_sng_dnrm;   // select line to m2stg_frac2
99input           m2stg_frac2_inf;        // select line to m2stg_frac2
100input           m1stg_snan_dbl_in2;     // operand 2 is double signalling NaN
101input           m1stg_snan_sng_in2;     // operand 2 is single signalling NaN
102input           m1stg_inf_zero_in;      // 1 operand is infinity; other is 0
103input           m1stg_inf_zero_in_dbl;  // 1 opnd is infinity; other is 0- dbl
104input           m1stg_dblop;            // double precision operation- mul 1 stg
105input           m1stg_dblop_inv;        // single or int operation- mul 1 stg
106input [105:0]   m4stg_frac;             // multiply array output
107input [5:0]     m4stg_sh_cnt_in;        // multiply normalization shift count
108input [6:0]     m3bstg_ld0_inv;         // leading 0's in multiply operands
109input           m4stg_left_shift_step;  // select line to m5stg_frac
110input           m4stg_right_shift_step; // select line to m5stg_frac
111input           m5stg_fmuls;            // fmuls- multiply 5 stage
112input           m5stg_fmulda;           // fmuld- multiply 5 stage
113input           mul_frac_out_fracadd;   // select line to mul_frac_out
114input           mul_frac_out_frac;      // select line to mul_frac_out
115input           m5stg_in_of;            // multiply overflow- select exp out
116input           m5stg_to_0;             // result to max finite on overflow
117input           fmul_clken_l;           // multiply pipe clk enable - asserted low
118input           rclk;           // global clock
119
120output [52:0]   m2stg_frac1_array_in;   // multiply array input 1
121output [52:0]   m2stg_frac2_array_in;   // multiply array input 2
122output [5:0]    m1stg_ld0_1;            // denorm operand 1 leading 0's
123output [5:0]    m1stg_ld0_2;            // denorm operand 2 leading 0's
124output          m4stg_frac_105;         // multiply stage 4a fraction input[105]
125output [6:0]    m3stg_ld0_inv;          // leading 0's in multiply operands
126output          m4stg_shl_54;           // multiply shift left output bit[54]
127output          m4stg_shl_55;           // multiply shift left output bit[55]
128output [32:0]   m5stg_frac_32_0;        // multiply stage 5 fraction input
129output          m5stg_frac_dbl_nx;      // double precision inexact result
130output          m5stg_frac_sng_nx;      // single precision inexact result
131output          m5stg_frac_neq_0;       // fraction input to mul 5 stage != 0
132output          m5stg_fracadd_cout;     // fraction rounding adder carry out
133output [51:0]   mul_frac_out;           // multiply fraction output
134
135input           se;                     // scan_enable
136input           si;                     // scan in
137output          so;                     // scan out
138
139
140wire [54:0]     mul_frac_in1;
141wire [54:0]     mul_frac_in2;
142wire [52:0]     m2stg_frac1_in;
143wire [52:0]     m2stg_frac1_array_in;
144wire [52:0]     m2stg_frac2_in;
145wire [52:0]     m2stg_frac2_array_in;
146wire [52:0]     m1stg_ld0_1_din;
147wire [5:0]      m1stg_ld0_1;
148wire [52:0]     m1stg_ld0_2_din;
149wire [5:0]      m1stg_ld0_2;
150wire            m4stg_frac_105;
151wire [5:0]      m4stg_sh_cnt_5;
152wire [5:0]      m4stg_sh_cnt_4;
153wire [5:0]      m4stg_sh_cnt;
154wire [6:0]      m3stg_ld0_inv;
155wire [168:63]   m4stg_shl_tmp;
156wire [55:0]     m4stg_shl;
157wire            m4stg_shl_54;
158wire            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;
162wire [168:0]    m4stg_shr_tmp;
163
164wire [55:0]     m4stg_shr;
165wire [54:0]     m5stg_frac_pre1_in;
166wire [54:0]     m5stg_frac_pre1;
167wire [54:0]     m5stg_frac_pre2_in;
168wire [54:0]     m5stg_frac_pre2;
169wire [54:0]     m5stg_frac_pre3_in;
170wire [54:0]     m5stg_frac_pre3;
171wire [54:0]     m5stg_frac_pre4_in;
172wire [54:0]     m5stg_frac_pre4;
173wire [54:33]    m5stg_frac_54_33;
174wire [32:0]     m5stg_frac_32_0;
175wire [54:3]     m5stg_fraca;
176wire [54:0]     m5stg_fracb;
177wire            m5stg_frac_dbl_nx;
178wire            m5stg_frac_sng_nx;
179wire            m5stg_frac_neq_0;
180wire [52:0]     m5stg_fracadd_tmp;
181wire            m5stg_fracadd_cout;
182wire [51:0]     m5stg_fracadd;
183wire [51:0]     mul_frac_out_in;
184wire [51:0]     mul_frac_out;
185wire [30:0] mstg_xtra_regs;
186
187wire se_l;
188
189assign se_l = ~se;
190
191clken_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
206dffe_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
218dffe_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
239assign 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
252assign m2stg_frac1_array_in[52:0]= (~m2stg_frac1_in[52:0]);
253
254assign 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 
268assign 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
279assign 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
284fpu_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
290assign 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
295fpu_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
310assign m4stg_frac_105= m4stg_frac[105];
311
312dffe_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
337assign m4stg_shl[55:0]= {m4stg_shl_tmp[168:114], (|m4stg_shl_tmp[113:63])};
338assign m4stg_shl_54= m4stg_shl[54];
339
340assign 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
351assign 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
368assign 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
373dff_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
390assign m5stg_frac_pre2_in[54:0]= ~({55{(m4stg_left_shift_step
391                                        && (!m4stg_shl[55]))}}
392                            & {m4stg_shl[53:0], 1'b0});
393
394dff_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
410assign m5stg_frac_pre3_in[54:0]= ~({55{(m4stg_right_shift_step
411                                        && m4stg_shr[55])}}
412                            & m4stg_shr[54:0]);
413
414dff_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
430assign m5stg_frac_pre4_in[54:0]= ~({55{(m4stg_right_shift_step
431                                        && (!m4stg_shr[55]))}}
432                            & {m4stg_shr[53:0], 1'b0});
433
434dff_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
451assign {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
457assign m5stg_fraca[54:3]= {m5stg_frac_54_33[54:33], m5stg_frac_32_0[32:3]};
458
459assign 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
470assign m5stg_frac_dbl_nx= (|m5stg_fracb[2:0]);
471
472assign m5stg_frac_sng_nx= m5stg_frac_dbl_nx || (|m5stg_fracb[31:3]);
473
474assign m5stg_frac_neq_0= m5stg_frac_sng_nx || (|m5stg_fracb[54:32]);
475
476assign m5stg_fracadd_tmp[52:0]= {1'b0, m5stg_fraca[54:3]}
477                        + {23'b0, m5stg_fmuls, 28'b0, m5stg_fmulda};
478
479assign m5stg_fracadd_cout= m5stg_fracadd_tmp[52];
480
481assign m5stg_fracadd[51:0]= m5stg_fracadd_tmp[51:0];
482
483assign 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
490dffe_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
502endmodule
503
504
Note: See TracBrowser for help on using the repository browser.