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

Revision 6, 12.4 KB checked in by pntsvt00, 14 years ago (diff)

versione iniziale opensparc

Line 
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T1 Processor File: fpu_div_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//      Divide pipeline fraction datapath.
24//
25///////////////////////////////////////////////////////////////////////////////
26
27
28module fpu_div_frac_dp (
29        inq_in1,
30        inq_in2,
31        d1stg_step,
32        div_norm_frac_in1_dbl_norm,
33        div_norm_frac_in1_dbl_dnrm,
34        div_norm_frac_in1_sng_norm,
35        div_norm_frac_in1_sng_dnrm,
36        div_norm_frac_in2_dbl_norm,
37        div_norm_frac_in2_dbl_dnrm,
38        div_norm_frac_in2_sng_norm,
39        div_norm_frac_in2_sng_dnrm,
40        div_norm_inf,
41        div_norm_qnan,
42        d1stg_dblop,
43        div_norm_zero,
44        d1stg_snan_dbl_in1,
45        d1stg_snan_sng_in1,
46        d1stg_snan_dbl_in2,
47        d1stg_snan_sng_in2,
48        d3stg_fdiv,
49        d6stg_fdiv,
50        d6stg_fdivd,
51        d6stg_fdivs,
52        div_frac_add_in2_load,
53        d6stg_frac_out_shl1,
54        d6stg_frac_out_nosh,
55        d4stg_fdiv,
56        div_frac_add_in1_add,
57        div_frac_add_in1_load,
58        d5stg_fdivb,
59        div_frac_out_add_in1,
60        div_frac_out_add,
61        div_frac_out_shl1_dbl,
62        div_frac_out_shl1_sng,
63        div_frac_out_of,
64        d7stg_to_0,
65        div_frac_out_load,
66        fdiv_clken_l,
67        rclk,
68       
69        div_shl_cnt,
70        d6stg_frac_0,
71        d6stg_frac_1,
72        d6stg_frac_2,
73        d6stg_frac_29,
74        d6stg_frac_30,
75        d6stg_frac_31,
76        div_frac_add_in1_neq_0,
77        div_frac_add_52_inv,
78        div_frac_add_52_inva,
79        div_frac_out_54_53,
80        div_frac_outa,
81
82        se,
83        si,
84        so
85);
86
87
88input [54:0]    inq_in1;                // request operand 1 to op pipes
89input [54:0]    inq_in2;                // request operand 2 to op pipes
90input           d1stg_step;             // divide pipe load
91input           div_norm_frac_in1_dbl_norm; // select line to div_norm
92input           div_norm_frac_in1_dbl_dnrm; // select line to div_norm
93input           div_norm_frac_in1_sng_norm; // select line to div_norm
94input           div_norm_frac_in1_sng_dnrm; // select line to div_norm
95input           div_norm_frac_in2_dbl_norm; // select line to div_norm
96input           div_norm_frac_in2_dbl_dnrm; // select line to div_norm
97input           div_norm_frac_in2_sng_norm; // select line to div_norm
98input           div_norm_frac_in2_sng_dnrm; // select line to div_norm
99input           div_norm_inf;           // select line to div_norm
100input           div_norm_qnan;          // select line to div_norm
101input           d1stg_dblop;            // double precision operation- d1 stg
102input           div_norm_zero;          // select line to div_norm
103input           d1stg_snan_dbl_in1;     // operand 1 is double signalling NaN
104input           d1stg_snan_sng_in1;     // operand 1 is single signalling NaN
105input           d1stg_snan_dbl_in2;     // operand 2 is double signalling NaN
106input           d1stg_snan_sng_in2;     // operand 2 is single signalling NaN
107input           d3stg_fdiv;             // divide operation- divide stage 3
108input           d6stg_fdiv;             // divide operation- divide stage 6
109input           d6stg_fdivd;            // divide double- divide stage 6
110input           d6stg_fdivs;            // divide single- divide stage 6
111input           div_frac_add_in2_load;  // load enable to div_frac_add_in2
112input           d6stg_frac_out_shl1;    // select line to d6stg_frac
113input           d6stg_frac_out_nosh;    // select line to d6stg_frac
114input           d4stg_fdiv;             // divide operation- divide stage 4
115input           div_frac_add_in1_add;   // select line to div_frac_add_in1
116input           div_frac_add_in1_load;  // load enable to div_frac_add_in1
117input           d5stg_fdivb;            // divide operation- divide stage 5
118input           div_frac_out_add_in1;   // select line to div_frac_out
119input           div_frac_out_add;       // select line to div_frac_out
120input           div_frac_out_shl1_dbl;  // select line to div_frac_out
121input           div_frac_out_shl1_sng;  // select line to div_frac_out
122input           div_frac_out_of;        // select line to div_frac_out
123input           d7stg_to_0;             // result to max finite on overflow
124input           div_frac_out_load;      // load enable to div_frac_out
125input           fdiv_clken_l;           // div pipe clk enable - asserted low
126input           rclk;           // global clock
127
128output [5:0]    div_shl_cnt;            // divide left shift amount
129output          d6stg_frac_0;           // divide fraction[0]- intermediate val
130output          d6stg_frac_1;           // divide fraction[1]- intermediate val
131output          d6stg_frac_2;           // divide fraction[2]- intermediate val
132output          d6stg_frac_29;          // divide fraction[29]- intermediate val
133output          d6stg_frac_30;          // divide fraction[30]- intermediate val
134output          d6stg_frac_31;          // divide fraction[31]- intermediate val
135output          div_frac_add_in1_neq_0; // div_frac_add_in1 != 0
136output          div_frac_add_52_inv;    // div_frac_add bit[52] inverted
137output          div_frac_add_52_inva;   // div_frac_add bit[52] inverted copy
138output [1:0]    div_frac_out_54_53;     // divide fraction output
139output [51:0]   div_frac_outa;          // divide fraction output- buffered copy
140
141input           se;                     // scan_enable
142input           si;                     // scan in
143output          so;                     // scan out
144
145
146wire [54:0]     div_frac_in1;
147wire [54:0]     div_frac_in2;
148wire [52:0]     div_norm_inv_in;
149wire [52:0]     div_norm_inv;
150wire [52:0]     div_norm;
151wire [5:0]      div_lead0;
152wire [5:0]      div_shl_cnt;
153wire [5:0]      div_shl_cnta;
154wire [52:0]     div_shl_data;
155wire [105:53]   div_shl_tmp;
156wire [52:0]     div_shl;
157wire [54:0]     div_shl_save;
158wire [54:0]     div_frac_add_in2_in;
159wire [54:0]     div_frac_add_in2;
160wire [53:0]     d6stg_frac;
161wire            d6stg_frac_0;
162wire            d6stg_frac_1;
163wire            d6stg_frac_2;
164wire            d6stg_frac_29;
165wire            d6stg_frac_30;
166wire            d6stg_frac_31;
167wire [54:0]     div_frac_add_in1_in;
168wire [54:0]     div_frac_add_in1;
169wire [54:0]     div_frac_add_in1a;
170wire            div_frac_add_in1_neq_0;
171wire [54:0]     div_frac_add;
172wire            div_frac_add_52_inv;
173wire            div_frac_add_52_inva;
174wire [54:0]     div_frac_out_in;
175wire  [1:0]     div_frac_out_54_53;
176wire [54:0]     div_frac_out;
177wire [51:0]     div_frac_outa;
178
179
180wire se_l;
181
182assign se_l = ~se;
183
184clken_buf  ckbuf_div_frac_dp (
185  .clk(clk),
186  .rclk(rclk),
187  .enb_l(fdiv_clken_l),
188  .tmb_l(se_l)
189  );
190
191///////////////////////////////////////////////////////////////////////////////
192//
193//      Divide fraction inputs.
194//
195///////////////////////////////////////////////////////////////////////////////
196
197dffe_s #(55) i_div_frac_in1 (
198        .din    (inq_in1[54:0]),
199        .en     (d1stg_step),
200        .clk    (clk),
201 
202        .q      (div_frac_in1[54:0]),
203
204        .se     (se),
205        .si     (),
206        .so     ()
207);
208
209dffe_s #(55) i_div_frac_in2 (
210        .din    (inq_in2[54:0]),
211        .en     (d1stg_step),
212        .clk    (clk),
213 
214        .q      (div_frac_in2[54:0]),
215
216        .se     (se),
217        .si     (),
218        .so     ()
219);
220
221
222///////////////////////////////////////////////////////////////////////////////
223//
224//      Divide normalization and special input injection.
225//
226///////////////////////////////////////////////////////////////////////////////
227
228assign div_norm_inv_in[52:0]= (~(({53{div_norm_frac_in1_dbl_norm}}
229                            & {1'b1, (div_frac_in1[51] || d1stg_snan_dbl_in1),
230                                div_frac_in1[50:0]})
231                | ({53{div_norm_frac_in1_dbl_dnrm}}
232                            & {div_frac_in1[51:0], 1'b0})
233                | ({53{div_norm_frac_in1_sng_norm}}
234                            & {1'b1, (div_frac_in1[54] || d1stg_snan_sng_in1),
235                                div_frac_in1[53:32], 29'b0})
236                | ({53{div_norm_frac_in1_sng_dnrm}}
237                            & {div_frac_in1[54:32], 30'b0})
238                | ({53{div_norm_frac_in2_dbl_norm}}
239                            & {1'b1, (div_frac_in2[51] || d1stg_snan_dbl_in2),
240                                div_frac_in2[50:0]})
241                | ({53{div_norm_frac_in2_dbl_dnrm}}
242                            & {div_frac_in2[51:0], 1'b0})
243                | ({53{div_norm_frac_in2_sng_norm}}
244                            & {1'b1, (div_frac_in2[54] || d1stg_snan_sng_in2),
245                                div_frac_in2[53:32], 29'b0})
246                | ({53{div_norm_frac_in2_sng_dnrm}}
247                            & {div_frac_in2[54:32], 30'b0})
248                | ({53{div_norm_inf}}
249                            & 53'h10000000000000)
250                | ({53{div_norm_qnan}}
251                            & {24'hffffff, {29{d1stg_dblop}}})
252                | ({53{div_norm_zero}}
253                            & 53'h00000000000000)));
254
255dff_s #(53) i_div_norm_inv (
256        .din    (div_norm_inv_in[52:0]),
257        .clk    (clk),
258
259        .q      (div_norm_inv[52:0]),
260
261        .se     (se),
262        .si     (),
263        .so     ()
264);
265
266assign div_norm[52:0]= (~div_norm_inv);
267
268
269///////////////////////////////////////////////////////////////////////////////
270//
271//      Divide lead zero count.
272//
273///////////////////////////////////////////////////////////////////////////////
274
275
276fpu_cnt_lead0_53b i_div_lead0 (
277        .din    (div_norm[52:0]),
278
279        .lead0 (div_lead0[5:0])
280);
281
282dff_s #12 i_dstg_xtra_regs (
283        .din    ({div_lead0[5:0], div_lead0[5:0]}),
284        .clk    (clk),
285
286        .q      ({div_shl_cnta[5:0], div_shl_cnt[5:0]}),
287
288        .se     (se),
289        .si     (),
290        .so     ()
291);
292
293
294///////////////////////////////////////////////////////////////////////////////
295//
296//      Divide left shift.
297//
298///////////////////////////////////////////////////////////////////////////////
299
300dff_s #(53) i_div_shl_data (
301        .din    (div_norm[52:0]),
302        .clk    (clk),
303
304        .q      (div_shl_data[52:0]),
305
306        .se     (se),
307        .si     (),
308        .so     ()
309);
310
311//assign div_shl_tmp[105:0]= {div_shl_data[52:0], 53'b0} << div_shl_cnta[5:0];
312  assign div_shl_tmp[105:53]= div_shl_data[52:0]         << div_shl_cnta[5:0];
313
314assign div_shl[52:0]= div_shl_tmp[105:53];
315
316dffe_s #(55) i_div_shl_save (
317        .din    ({2'b0, div_shl[52:0]}),
318        .en     (d3stg_fdiv),
319        .clk    (clk),
320 
321        .q      (div_shl_save[54:0]),
322 
323        .se     (se),
324        .si     (),
325        .so     ()
326);
327
328assign div_frac_add_in2_in[54:0]= ({55{d4stg_fdiv}}
329                            & (~{2'b0, div_shl[52:0]}))
330                | ({55{d6stg_fdiv}}
331                            & {25'b0, d6stg_fdivs, 28'b0, d6stg_fdivd});
332
333dffe_s #(55) i_div_frac_add_in2 (
334        .din    (div_frac_add_in2_in[54:0]),
335        .en     (div_frac_add_in2_load),
336        .clk    (clk),
337
338        .q      (div_frac_add_in2[54:0]),
339
340        .se     (se),
341        .si     (),
342        .so     ()
343);
344
345
346///////////////////////////////////////////////////////////////////////////////
347//
348//      Divide adder/subtractor 2nd input.
349//
350///////////////////////////////////////////////////////////////////////////////
351
352assign d6stg_frac[53:0]= ({54{d6stg_frac_out_shl1}}
353                            & {div_frac_out[52:0], 1'b0})
354                | ({54{d6stg_frac_out_nosh}}
355                            & div_frac_out[53:0]);
356
357assign d6stg_frac_0= d6stg_frac[0];
358assign d6stg_frac_1= d6stg_frac[1];
359assign d6stg_frac_2= d6stg_frac[2];
360assign d6stg_frac_29= d6stg_frac[29];
361assign d6stg_frac_30= d6stg_frac[30];
362assign d6stg_frac_31= d6stg_frac[31];
363
364assign div_frac_add_in1_in[54:0]= ({55{d4stg_fdiv}}
365                            & div_shl_save[54:0])
366                | ({55{(div_frac_add_in1_add && (!div_frac_add[54]))}}
367                            & {div_frac_add[53:0], 1'b0})
368                | ({55{(div_frac_add_in1_add && div_frac_add[54])}}
369                            & {div_frac_add_in1[53:0], 1'b0})
370                | ({55{d6stg_fdiv}}
371                            & {3'b0, d6stg_frac[53:31],
372                                (d6stg_frac[30:2] & {29{d6stg_fdivd}})});
373
374dffe_s #(55) i_div_frac_add_in1 (
375        .din    (div_frac_add_in1_in[54:0]),
376        .en     (div_frac_add_in1_load),
377        .clk    (clk),
378
379        .q      (div_frac_add_in1[54:0]),
380
381        .se     (se),
382        .si     (),
383        .so     ()
384);
385
386dffe_s #(55) i_div_frac_add_in1a (
387        .din    (div_frac_add_in1_in[54:0]),
388        .en     (div_frac_add_in1_load),
389        .clk    (clk),
390
391        .q      (div_frac_add_in1a[54:0]),
392
393        .se     (se),
394        .si     (),
395        .so     ()
396);
397
398assign div_frac_add_in1_neq_0= (|div_frac_add_in1[54:0]);
399
400
401///////////////////////////////////////////////////////////////////////////////
402//
403//      Divide adder/subtractor.
404//
405///////////////////////////////////////////////////////////////////////////////
406
407assign div_frac_add[54:0]= (div_frac_add_in1a[54:0]
408                        + div_frac_add_in2[54:0]
409                        + {54'b0, d5stg_fdivb});
410
411assign div_frac_add_52_inv= (!div_frac_add[52]);
412assign div_frac_add_52_inva= (!div_frac_add[52]);
413
414assign div_frac_out_in[54:0]= ({55{d4stg_fdiv}}
415                            & 55'b0)
416                | ({55{div_frac_out_add_in1}}
417                            & div_frac_add_in1[54:0])
418                | ({55{div_frac_out_add}}
419                            & div_frac_add[54:0])
420                | ({55{div_frac_out_shl1_dbl}}
421                            & {div_frac_out[53:0], (!div_frac_add[54])})
422                | ({55{div_frac_out_shl1_sng}}
423                            & {div_frac_out[53:29], (!div_frac_add[54]), 29'b0})
424                | ({55{div_frac_out_of}}
425                            & {55{d7stg_to_0}});
426
427dffe_s #(55) i_div_frac_out (
428        .din    (div_frac_out_in[54:0]),
429        .en     (div_frac_out_load),
430        .clk    (clk),
431
432        .q      (div_frac_out[54:0]),
433
434        .se     (se),
435        .si     (),
436        .so     ()
437);
438
439assign div_frac_out_54_53[1:0] = div_frac_out[54:53];
440
441assign div_frac_outa[51:0]= div_frac_out[51:0];
442
443endmodule
444
445
Note: See TracBrowser for help on using the repository browser.