blob: fdcf27c1d5a0e0c7e547de9bc06e8c34a7605cf4 [file] [log] [blame]
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T1 Processor File: fpu_add_exp_dp.v
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
//
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
//
// The above named program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// ========== Copyright Header End ============================================
///////////////////////////////////////////////////////////////////////////////
//
// Add pipeline exponent datapath.
//
///////////////////////////////////////////////////////////////////////////////
module fpu_add_exp_dp (
inq_in1,
inq_in2,
inq_op,
inq_op_7,
a1stg_step,
a1stg_faddsubd,
a1stg_faddsubs,
a1stg_fsdtoix,
a6stg_step,
a1stg_fstod,
a1stg_fdtos,
a1stg_fstoi,
a1stg_fstox,
a1stg_fdtoi,
a1stg_fdtox,
a2stg_fsdtoix_fdtos,
a2stg_faddsubop,
a2stg_fitos,
a2stg_fitod,
a2stg_fxtos,
a2stg_fxtod,
a3stg_exp_7ff,
a3stg_exp_ff,
a3stg_exp_add,
a3stg_inc_exp_inv,
a3stg_same_exp_inv,
a3stg_dec_exp_inv,
a3stg_faddsubop,
a3stg_fdtos_inv,
a4stg_fixtos_fxtod_inv,
a4stg_shl_cnt,
a4stg_denorm_inv,
a4stg_rndadd_cout,
add_exp_out_expinc,
add_exp_out_exp,
add_exp_out_exp1,
a4stg_in_of,
add_exp_out_expadd,
a4stg_dblop,
a4stg_to_0_inv,
fadd_clken_l,
rclk,
a1stg_expadd3_11,
a1stg_expadd1_11_0,
a1stg_expadd4_inv,
a1stg_expadd2_5_0,
a2stg_exp,
a2stg_expadd,
a3stg_exp_10_0,
a4stg_exp_11_0,
add_exp_out,
se,
si,
so
);
input [62:52] inq_in1; // request operand 1 to op pipes
input [62:52] inq_in2; // request operand 2 to op pipes
input [1:0] inq_op; // request opcode[1:0]
input inq_op_7; // request opcode[7]
input a1stg_step; // add pipe load
input a1stg_faddsubd; // add/subtract double- add 1 stg
input a1stg_faddsubs; // add/subtract single- add 1 stg
input a1stg_fsdtoix; // float to integer convert- add 1 stg
input a6stg_step; // advance the add pipe
input a1stg_fstod; // fstod- add 1 stage
input a1stg_fdtos; // fdtos- add 1 stage
input a1stg_fstoi; // fstoi- add 1 stage
input a1stg_fstox; // fstox- add 1 stage
input a1stg_fdtoi; // fdtoi- add 1 stage
input a1stg_fdtox; // fdtox- add 1 stage
input a2stg_fsdtoix_fdtos; // float to integer convert- add 2 stg
input a2stg_faddsubop; // float add or subtract- add 2 stage
input a2stg_fitos; // fitos- add 2 stage
input a2stg_fitod; // fitod- add 2 stage
input a2stg_fxtos; // fxtos- add 2 stage
input a2stg_fxtod; // fxtod- add 2 stage
input a3stg_exp_7ff; // select line to a3stg_exp
input a3stg_exp_ff; // select line to a3stg_exp
input a3stg_exp_add; // select line to a3stg_exp
input a3stg_inc_exp_inv; // increment the exponent- add 3 stg
input a3stg_same_exp_inv; // keep the exponent- add 3 stg
input a3stg_dec_exp_inv; // decrement the exponent- add 3 stg
input a3stg_faddsubop; // add/subtract- add 3 stage
input a3stg_fdtos_inv; // double to single convert- add 3 stg
input a4stg_fixtos_fxtod_inv; // int to single/double cvt- add 4 stg
input [5:0] a4stg_shl_cnt; // postnorm shift left count- add 4 stg
input a4stg_denorm_inv; // 0 the exponent
input a4stg_rndadd_cout; // fraction rounding adder carry out
input add_exp_out_expinc; // select line to add_exp_out
input add_exp_out_exp; // select line to add_exp_out
input add_exp_out_exp1; // select line to add_exp_out
input a4stg_in_of; // add overflow- select exp out
input add_exp_out_expadd; // select line to add_exp_out
input a4stg_dblop; // double precision operation- add 4 stg
input a4stg_to_0_inv; // result to infinity on overflow
input fadd_clken_l; // add pipe clk enable - asserted low
input rclk; // global clock
output a1stg_expadd3_11; // exponent adder 3 output- add 1 stage
output [11:0] a1stg_expadd1_11_0; // exponent adder 1 output- add 1 stage
output [10:0] a1stg_expadd4_inv; // exponent adder 4 output- add 1 stage
output [5:0] a1stg_expadd2_5_0; // exponent adder 2 output- add 1 stage
output [11:0] a2stg_exp; // exponent- add 2 stage
output [12:0] a2stg_expadd; // exponent adder- add 2 stage
output [10:0] a3stg_exp_10_0; // exponent adder- add 3 stage
output [11:0] a4stg_exp_11_0; // exponent adder- add 4 stage
output [10:0] add_exp_out; // add exponent output
input se; // scan_enable
input si; // scan in
output so; // scan out
wire [62:52] a1stg_in1;
wire [62:52] a1stg_in1a;
wire [62:52] a1stg_in2;
wire [62:52] a1stg_in2a;
wire [12:0] a1stg_dp_sngop;
wire [12:0] a1stg_dp_sngopa;
wire [12:0] a1stg_dp_dblop;
wire [12:0] a1stg_dp_dblopa;
wire [9:7] a1stg_op_7;
wire a1stg_op_7_0;
wire [10:0] a1stg_expadd3_in1;
wire [10:0] a1stg_expadd3_in2_in;
wire [10:0] a1stg_expadd3_in2;
wire [12:0] a1stg_expadd3;
wire a1stg_expadd3_11;
wire [12:0] a1stg_expadd1_in1;
wire [12:0] a1stg_expadd1_in2;
wire [12:0] a1stg_expadd1;
wire [11:0] a1stg_expadd1_11_0;
wire [12:0] a1stg_expadd4_in1;
wire [12:0] a1stg_expadd4_in2;
wire [12:0] a1stg_expadd4;
wire [10:0] a1stg_expadd4_inv;
wire [12:0] a1stg_expadd2_in1;
wire [12:0] a1stg_expadd2;
wire [5:0] a1stg_expadd2_5_0;
wire [12:0] a2stg_exp_in;
wire [11:0] a2stg_exp;
wire [12:0] a2stg_expa;
wire [12:0] a2stg_expadd_in2_in;
wire [12:0] a2stg_expadd_in2;
wire [12:0] a2stg_expadd;
wire [12:0] a3stg_exp_in;
wire [12:0] a3stg_exp;
wire [10:0] a3stg_exp_10_0;
wire [12:0] a3stg_exp_plus1;
wire [12:0] a3stg_exp_minus1;
wire [12:0] a4stg_exp_pre1_in;
wire [12:0] a4stg_exp_pre1;
wire [12:0] a4stg_exp_pre3_in;
wire [12:0] a4stg_exp_pre3;
wire [12:0] a4stg_exp_pre2_in;
wire [12:0] a4stg_exp_pre2;
wire [12:0] a4stg_exp_pre4_in;
wire [12:0] a4stg_exp_pre4;
wire [12:0] a4stg_exp;
wire [11:0] a4stg_exp_11_0;
wire [12:0] a4stg_exp2;
wire [12:0] a4stg_expinc;
wire [12:0] a4stg_expadd_in2;
wire [12:0] a4stg_expadd;
wire [12:0] a4stg_expshl;
wire [10:0] add_exp_out_in1;
wire [10:0] add_exp_out1;
wire [10:0] add_exp_out_in2;
wire [10:0] add_exp_out2;
wire [10:0] add_exp_out_in3;
wire [10:0] add_exp_out3;
wire [10:0] add_exp_out4;
wire [10:0] add_exp_out;
// 6/23/03: Removed tm_l input port. Using locally generated se_l instead for cken_buf
wire se_l;
assign se_l = ~se;
clken_buf ckbuf_add_exp_dp (
.clk(clk),
.rclk(rclk),
.enb_l(fadd_clken_l),
.tmb_l(se_l)
);
///////////////////////////////////////////////////////////////////////////////
//
// Add exponent inputs.
//
// Add input stage.
//
///////////////////////////////////////////////////////////////////////////////
dffe_s #(11) i_a1stg_in1 (
.din (inq_in1[62:52]),
.en (a1stg_step),
.clk (clk),
.q (a1stg_in1[62:52]),
.se (se),
.si (),
.so ()
);
dffe_s #(11) i_a1stg_in1a (
.din (inq_in1[62:52]),
.en (a1stg_step),
.clk (clk),
.q (a1stg_in1a[62:52]),
.se (se),
.si (),
.so ()
);
dffe_s #(11) i_a1stg_in2 (
.din (inq_in2[62:52]),
.en (a1stg_step),
.clk (clk),
.q (a1stg_in2[62:52]),
.se (se),
.si (),
.so ()
);
dffe_s #(11) i_a1stg_in2a (
.din (inq_in2[62:52]),
.en (a1stg_step),
.clk (clk),
.q (a1stg_in2a[62:52]),
.se (se),
.si (),
.so ()
);
dffe_s #(13) i_a1stg_dp_sngop (
.din ({13{inq_op[0]}}),
.en (a1stg_step),
.clk (clk),
.q (a1stg_dp_sngop[12:0]),
.se (se),
.si (),
.so ()
);
dffe_s #(13) i_a1stg_dp_sngopa (
.din ({13{inq_op[0]}}),
.en (a1stg_step),
.clk (clk),
.q (a1stg_dp_sngopa[12:0]),
.se (se),
.si (),
.so ()
);
dffe_s #(13) i_a1stg_dp_dblop (
.din ({13{inq_op[1]}}),
.en (a1stg_step),
.clk (clk),
.q (a1stg_dp_dblop[12:0]),
.se (se),
.si (),
.so ()
);
dffe_s #(13) i_a1stg_dp_dblopa (
.din ({13{inq_op[1]}}),
.en (a1stg_step),
.clk (clk),
.q (a1stg_dp_dblopa[12:0]),
.se (se),
.si (),
.so ()
);
dffe_s #(4) i_a1stg_op_7 (
.din ({4{inq_op_7}}),
.en (a1stg_step),
.clk (clk),
.q ({a1stg_op_7[9:7], a1stg_op_7_0}),
.se (se),
.si (),
.so ()
);
dffe_s #(11) i_a1stg_expadd3_in1 (
.din (inq_in1[62:52]),
.en (a1stg_step),
.clk (clk),
.q (a1stg_expadd3_in1[10:0]),
.se (se),
.si (),
.so ()
);
assign a1stg_expadd3_in2_in[10:0]= (~(inq_in2[62:52]
& {8'hff, {3{inq_op[1]}}}));
dffe_s #(11) i_a1stg_expadd3_in2 (
.din (a1stg_expadd3_in2_in[10:0]),
.en (a1stg_step),
.clk (clk),
.q (a1stg_expadd3_in2[10:0]),
.se (se),
.si (),
.so ()
);
///////////////////////////////////////////////////////////////////////////////
//
// Add pipe exponent comparison.
//
// Add stage 1.
//
///////////////////////////////////////////////////////////////////////////////
assign a1stg_expadd3[12:0]= ({2'b00, a1stg_expadd3_in1[10:0]}
+ {2'b11, a1stg_expadd3_in2[10:0]}
+ 13'h0001);
assign a1stg_expadd3_11 = a1stg_expadd3[11];
assign a1stg_expadd1_in1[12:0]= (a1stg_dp_dblopa
& {2'b0, a1stg_in1[62:52]})
| (a1stg_dp_sngopa
& {5'b0, a1stg_in1[62:55]})
| {3'b0, a1stg_op_7[9:7], 6'b0, a1stg_op_7_0};
assign a1stg_expadd1_in2[12:0]= (~((a1stg_dp_dblop
& {2'b0, a1stg_in2[62:52]})
| (a1stg_dp_sngop
& {5'b0, a1stg_in2[62:55]})));
assign a1stg_expadd1[12:0]= (a1stg_expadd1_in1[12:0]
+ a1stg_expadd1_in2[12:0]
+ 13'h0001);
assign a1stg_expadd1_11_0[11:0] = a1stg_expadd1[11:0];
assign a1stg_expadd4_in1[12:0]= (a1stg_dp_dblopa
& {2'b0, a1stg_in2a[62:52]})
| (a1stg_dp_sngopa
& {5'b0, a1stg_in2a[62:55]});
assign a1stg_expadd4_in2[12:0]= (~((a1stg_dp_dblop
& {2'b0, a1stg_in1a[62:52]})
| (a1stg_dp_sngop
& {5'b0, a1stg_in1a[62:55]})));
assign a1stg_expadd4[12:0]= (a1stg_expadd4_in1[12:0]
+ a1stg_expadd4_in2[12:0]
+ 13'h0001);
assign a1stg_expadd4_inv[10:0]= (~a1stg_expadd4[10:0]);
assign a1stg_expadd2_in1[12:0]= (a1stg_dp_dblopa
& {2'b0, a1stg_in2a[62:52]})
| (a1stg_dp_sngopa
& {5'b0, a1stg_in2a[62:55]});
assign a1stg_expadd2[12:0]= (a1stg_expadd2_in1[12:0]
+ 13'h0001);
assign a1stg_expadd2_5_0[5:0] = a1stg_expadd2[5:0];
assign a2stg_exp_in[12:0]= ({13{(a1stg_faddsubd && (!a1stg_expadd1[12]))}}
& {2'b0, a1stg_in1a[62:52]})
| ({13{(a1stg_faddsubs && (!a1stg_expadd1[12]))}}
& {5'b0, a1stg_in1a[62:55]})
| ({13{(a1stg_faddsubd && a1stg_expadd1[12])}}
& {2'b0, a1stg_in2[62:52]})
| ({13{a1stg_fdtos}}
& {2'b0, a1stg_in2[62:52]})
| ({13{(a1stg_faddsubs && a1stg_expadd1[12])}}
& {5'b0, a1stg_in2[62:55]})
| ({13{a1stg_fstod}}
& {5'b0, a1stg_in2[62:55]})
| ({13{a1stg_fsdtoix}}
& a1stg_expadd2[12:0]);
dffe_s #(12) i_a2stg_exp (
.din (a2stg_exp_in[11:0]),
.en (a6stg_step),
.clk (clk),
.q (a2stg_exp[11:0]),
.se (se),
.si (),
.so ()
);
dffe_s #(13) i_a2stg_expa (
.din (a2stg_exp_in[12:0]),
.en (a6stg_step),
.clk (clk),
.q (a2stg_expa[12:0]),
.se (se),
.si (),
.so ()
);
///////////////////////////////////////////////////////////////////////////////
//
// Add pipe exponent adjustment.
//
// Add stage 1.
//
///////////////////////////////////////////////////////////////////////////////
assign a2stg_expadd_in2_in[12:0]= ({13{a1stg_fstod}}
& 13'h0380)
| ({13{a1stg_fdtos}}
& (~13'h0380))
| ({13{a1stg_fstoi}}
& (~13'h009f))
| ({13{a1stg_fstox}}
& (~13'h00bf))
| ({13{a1stg_fdtoi}}
& (~13'h041f))
| ({13{a1stg_fdtox}}
& (~13'h043f));
dffe_s #(13) i_a2stg_expadd2_in2 (
.din (a2stg_expadd_in2_in[12:0]),
.en (a6stg_step),
.clk (clk),
.q (a2stg_expadd_in2[12:0]),
.se (se),
.si (),
.so ()
);
///////////////////////////////////////////////////////////////////////////////
//
// Add pipe exponent adjustment.
//
// Add stage 2.
//
///////////////////////////////////////////////////////////////////////////////
assign a2stg_expadd[12:0]= (a2stg_expa[12:0]
+ a2stg_expadd_in2[12:0]
+ {12'b0, a2stg_fsdtoix_fdtos});
assign a3stg_exp_in[12:0]= ({13{a2stg_faddsubop}}
& a2stg_expa[12:0])
| ({13{a2stg_fitos}}
& 13'h009e)
| ({13{a2stg_fitod}}
& 13'h041e)
| ({13{a2stg_fxtos}}
& 13'h00be)
| ({13{a2stg_fxtod}}
& 13'h043e)
| ({13{a3stg_exp_7ff}}
& 13'h07ff)
| ({13{a3stg_exp_ff}}
& 13'h00ff)
| ({13{a3stg_exp_add}}
& (a2stg_expadd[12:0] & {13{(!a2stg_expadd[11])}}));
dffe_s #(13) i_a3stg_exp (
.din (a3stg_exp_in[12:0]),
.en (a6stg_step),
.clk (clk),
.q (a3stg_exp[12:0]),
.se (se),
.si (),
.so ()
);
assign a3stg_exp_10_0[10:0] = a3stg_exp[10:0];
///////////////////////////////////////////////////////////////////////////////
//
// Add pipe exponent increment/decrement adjustment.
//
// Add stage 3.
//
///////////////////////////////////////////////////////////////////////////////
assign a3stg_exp_plus1[12:0]= a3stg_exp[12:0] + 13'h0001;
assign a3stg_exp_minus1[12:0]= a3stg_exp[12:0] - 13'h0001;
assign a4stg_exp_pre1_in[12:0]= ({13{(a3stg_faddsubop && a6stg_step
&& (!a3stg_inc_exp_inv))}}
& a3stg_exp_plus1[12:0]);
dff_s #(13) i_a4stg_exp_pre1 (
.din (a4stg_exp_pre1_in[12:0]),
.clk (clk),
.q (a4stg_exp_pre1[12:0]),
.se (se),
.si (),
.so ()
);
assign a4stg_exp_pre3_in[12:0]= ({13{(a3stg_faddsubop && a6stg_step
&& (!a3stg_dec_exp_inv))}}
& a3stg_exp_minus1[12:0]);
dff_s #(13) i_a4stg_exp_pre3 (
.din (a4stg_exp_pre3_in[12:0]),
.clk (clk),
.q (a4stg_exp_pre3[12:0]),
.se (se),
.si (),
.so ()
);
assign a4stg_exp_pre2_in[12:0]= ({13{((!a3stg_fdtos_inv) && a6stg_step)}}
& a3stg_exp[12:0])
| ({13{((!a4stg_fixtos_fxtod_inv) && a6stg_step)}}
& a4stg_expshl[12:0])
| ({13{(!a6stg_step)}}
& a4stg_exp[12:0]);
dff_s #(13) i_a4stg_exp_pre2 (
.din (a4stg_exp_pre2_in[12:0]),
.clk (clk),
.q (a4stg_exp_pre2[12:0]),
.se (se),
.si (),
.so ()
);
assign a4stg_exp_pre4_in[12:0]= ({13{(a3stg_faddsubop && a6stg_step
&& (!a3stg_same_exp_inv))}}
& a3stg_exp[12:0]);
dff_s #(13) i_a4stg_exp_pre4 (
.din (a4stg_exp_pre4_in[12:0]),
.clk (clk),
.q (a4stg_exp_pre4[12:0]),
.se (se),
.si (),
.so ()
);
dffe_s #(13) i_a4stg_exp2 (
.din (a3stg_exp[12:0]),
.en (a6stg_step),
.clk (clk),
.q (a4stg_exp2[12:0]),
.se (se),
.si (),
.so ()
);
///////////////////////////////////////////////////////////////////////////////
//
// Add pipe exponent rounding increment.
//
// Add stage 4.
//
///////////////////////////////////////////////////////////////////////////////
assign a4stg_exp[12:0]= (a4stg_exp_pre1[12:0]
| a4stg_exp_pre2[12:0]
| a4stg_exp_pre3[12:0]
| a4stg_exp_pre4[12:0]);
assign a4stg_exp_11_0[11:0] = a4stg_exp[11:0];
assign a4stg_expinc[12:0]= a4stg_exp[12:0] + 13'h0001;
///////////////////////////////////////////////////////////////////////////////
//
// Add pipe exponent adjustment for post normalization left shift.
//
// Add stage 4.
//
///////////////////////////////////////////////////////////////////////////////
assign a4stg_expadd_in2[12:0]= (~{7'b0, a4stg_shl_cnt[5:0]});
assign a4stg_expadd[12:0]= (a4stg_exp2[12:0]
+ a4stg_expadd_in2[12:0]
+ 13'h0001);
///////////////////////////////////////////////////////////////////////////////
//
// Add pipe exponent output.
//
// Add stage 4.
//
///////////////////////////////////////////////////////////////////////////////
assign a4stg_expshl[12:0]= (a4stg_expadd[12:0] & {13{a4stg_denorm_inv}});
assign add_exp_out_in1[10:0]= (~(({11{add_exp_out_exp1}}
& a4stg_exp[10:0])
| ({11{a4stg_in_of}}
& {{3{a4stg_dblop}}, 7'h7f, a4stg_to_0_inv})
| ({11{add_exp_out_expadd}}
& a4stg_expshl[10:0])));
dffe_s #(11) i_add_exp_out1 (
.din (add_exp_out_in1[10:0]),
.en (a6stg_step),
.clk (clk),
.q (add_exp_out1[10:0]),
.se (se),
.si (),
.so ()
);
assign add_exp_out_in2[10:0]= (~({11{(add_exp_out_expinc
&& a4stg_rndadd_cout)}}
& a4stg_expinc[10:0]));
dffe_s #(11) i_add_exp_out2 (
.din (add_exp_out_in2[10:0]),
.en (a6stg_step),
.clk (clk),
.q (add_exp_out2[10:0]),
.se (se),
.si (),
.so ()
);
assign add_exp_out_in3[10:0]= (~({11{add_exp_out_exp}}
& a4stg_exp[10:0]));
dffe_s #(11) i_add_exp_out3 (
.din (add_exp_out_in3[10:0]),
.en (a6stg_step),
.clk (clk),
.q (add_exp_out3[10:0]),
.se (se),
.si (),
.so ()
);
dffe_s #(11) i_add_exp_out4 (
.din ({11{a4stg_rndadd_cout}}),
.en (a6stg_step),
.clk (clk),
.q (add_exp_out4[10:0]),
.se (se),
.si (),
.so ()
);
assign add_exp_out[10:0]= (~(add_exp_out1[10:0]
& add_exp_out2[10:0]
& (add_exp_out3[10:0] | add_exp_out4[10:0])));
endmodule