// ========== Copyright Header Begin ========================================== // // OpenSPARC T1 Processor File: fpu_mul_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 ============================================ /////////////////////////////////////////////////////////////////////////////// // // Multiply pipeline exponent datapath. // /////////////////////////////////////////////////////////////////////////////// module fpu_mul_exp_dp ( inq_in1, inq_in2, m6stg_step, m1stg_dblop, m1stg_sngop, m2stg_exp_expadd, m2stg_exp_0bff, m2stg_exp_017f, m2stg_exp_04ff, m2stg_exp_zero, m1stg_fsmuld, m2stg_fmuld, m2stg_fmuls, m2stg_fsmuld, m3stg_ld0_inv, m5stg_fracadd_cout, mul_exp_out_exp_plus1, mul_exp_out_exp, m5stg_in_of, m5stg_fmuld, m5stg_to_0_inv, m4stg_shl_54, m4stg_shl_55, m4stg_inc_exp_54, m4stg_inc_exp_55, m4stg_inc_exp_105, fmul_clken_l, rclk, m3stg_exp, m3stg_expadd_eq_0, m3stg_expadd_lte_0_inv, m4stg_exp, m5stg_exp, mul_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 m6stg_step; // advance the multiply pipe input m1stg_dblop; // double precision operation- mul 1 stg input m1stg_sngop; // single precision operation- mul 1 stg input m2stg_exp_expadd; // select line to m2stg_exp input m2stg_exp_0bff; // select line to m2stg_exp input m2stg_exp_017f; // select line to m2stg_exp input m2stg_exp_04ff; // select line to m2stg_exp input m2stg_exp_zero; // select line to m2stg_exp input m1stg_fsmuld; // fsmuld- multiply 1 stage input m2stg_fmuld; // fmuld- multiply 2 stage input m2stg_fmuls; // fmuls- multiply 2 stage input m2stg_fsmuld; // fsmuld- multiply 2 stage input [6:0] m3stg_ld0_inv; // leading 0's in multiply operands input m4stg_inc_exp_54; // select line to m5stg_exp input m4stg_inc_exp_55; // select line to m5stg_exp input m4stg_inc_exp_105; // select line to m5stg_exp input m5stg_fracadd_cout; // fraction rounding adder carry out input mul_exp_out_exp_plus1; // select line to mul_exp_out input mul_exp_out_exp; // select line to mul_exp_out input m5stg_in_of; // multiply overflow- select exp out input m5stg_fmuld; // fmuld- multiply 5 stage input m5stg_to_0_inv; // result to infinity on overflow input m4stg_shl_54; // multiply shift left output bit[54] input m4stg_shl_55; // multiply shift left output bit[55] input fmul_clken_l; // multiply pipe clk enable - asserted low input rclk; // global clock output [12:0] m3stg_exp; // exponent input- multiply 3 stage output m3stg_expadd_eq_0; // mul stage 3 exponent adder sum == 0 output m3stg_expadd_lte_0_inv; // mul stage 3 exponent adder sum <= 0 output [12:0] m4stg_exp; // exponent input- multiply 4 stage output [12:0] m5stg_exp; // exponent input- multiply 5 stage output [10:0] mul_exp_out; // multiply exponent output input se; // scan_enable input si; // scan in output so; // scan out wire [10:0] m1stg_exp_in1; wire [10:0] m1stg_exp_in2; wire [12:0] m1stg_expadd_in1; wire [12:0] m1stg_expadd_in2; wire [12:0] m1stg_expadd; wire [12:0] m2stg_exp_in; wire [12:0] m2stg_exp; wire [12:0] m2stg_expadd_in2; wire [12:0] m2stg_expadd; wire [12:0] m3astg_exp; wire [12:0] m3bstg_exp; wire [12:0] m3stg_exp; wire [12:0] m3stg_expa; wire [12:0] m3stg_expadd; wire m3stg_expadd_eq_0; wire m3stg_expadd_lte_0_inv; wire [12:0] m4stg_exp_in; wire [12:0] m4stg_exp; wire [12:0] m4stg_exp_plus1; wire [12:0] m5stg_exp_pre1_in; wire [12:0] m5stg_exp_pre1; wire [12:0] m5stg_exp_pre2_in; wire [12:0] m5stg_exp_pre2; wire [12:0] m5stg_exp_pre3_in; wire [12:0] m5stg_exp_pre3; wire [12:0] m5stg_exp; wire [12:0] m5stg_expa; wire [12:0] m5stg_exp_plus1; wire [10:0] mul_exp_out_in; wire [10:0] mul_exp_out; wire se_l; assign se_l = ~se; clken_buf ckbuf_mul_exp_dp ( .clk(clk), .rclk(rclk), .enb_l(fmul_clken_l), .tmb_l(se_l) ); /////////////////////////////////////////////////////////////////////////////// // // Multiply exponent inputs. // /////////////////////////////////////////////////////////////////////////////// dffe_s #(11) i_m1stg_exp_in1 ( .din (inq_in1[62:52]), .en (m6stg_step), .clk (clk), .q (m1stg_exp_in1[10:0]), .se (se), .si (), .so () ); dffe_s #(11) i_m1stg_exp_in2 ( .din (inq_in2[62:52]), .en (m6stg_step), .clk (clk), .q (m1stg_exp_in2[10:0]), .se (se), .si (), .so () ); /////////////////////////////////////////////////////////////////////////////// // // Multiply exponent adder. // // Multiply stage 1. // /////////////////////////////////////////////////////////////////////////////// assign m1stg_expadd_in1[12:0]= ({13{m1stg_dblop}} & {2'b0, m1stg_exp_in1[10:0]}) | ({13{m1stg_sngop}} & {5'b0, m1stg_exp_in1[10:3]}); assign m1stg_expadd_in2[12:0]= ({13{m1stg_dblop}} & {2'b0, m1stg_exp_in2[10:0]}) | ({13{m1stg_sngop}} & {5'b0, m1stg_exp_in2[10:3]}); assign m1stg_expadd[12:0]= (m1stg_expadd_in1[12:0] + m1stg_expadd_in2[12:0] + 13'h0001); assign m2stg_exp_in[12:0]= ({13{m2stg_exp_expadd}} & m1stg_expadd[12:0]) | ({13{m2stg_exp_0bff}} & 13'h0bff) | ({13{m2stg_exp_017f}} & 13'h017f) | ({13{m2stg_exp_04ff}} & 13'h04ff) | ({13{m2stg_exp_zero}} & {{3{m1stg_fsmuld}}, 10'b0}); dffe_s #(13) i_m2stg_exp ( .din (m2stg_exp_in[12:0]), .en (m6stg_step), .clk (clk), .q (m2stg_exp[12:0]), .se (se), .si (), .so () ); /////////////////////////////////////////////////////////////////////////////// // // Multiply exponent adder. // // Multiply stage 2. // /////////////////////////////////////////////////////////////////////////////// assign m2stg_expadd_in2[12:0]= ({13{m2stg_fmuld}} & 13'h1c00) | ({13{m2stg_fmuls}} & 13'h1f80) | ({13{m2stg_fsmuld}} & 13'h0300); assign m2stg_expadd[12:0]= m2stg_exp[12:0] + m2stg_expadd_in2[12:0]; dffe_s #(13) i_m3astg_exp ( .din (m2stg_expadd[12:0]), .en (m6stg_step), .clk (clk), .q (m3astg_exp[12:0]), .se (se), .si (), .so () ); /////////////////////////////////////////////////////////////////////////////// // // Multiply exponent. // // Multiply stage 3a. // /////////////////////////////////////////////////////////////////////////////// dffe_s #(13) i_m3bstg_exp ( .din (m3astg_exp[12:0]), .en (m6stg_step), .clk (clk), .q (m3bstg_exp[12:0]), .se (se), .si (), .so () ); /////////////////////////////////////////////////////////////////////////////// // // Multiply exponent. // // Multiply stage 3b. // /////////////////////////////////////////////////////////////////////////////// dffe_s #(13) i_m3stg_exp ( .din (m3bstg_exp[12:0]), .en (m6stg_step), .clk (clk), .q (m3stg_exp[12:0]), .se (se), .si (), .so () ); dffe_s #(13) i_m3stg_expa ( .din (m3bstg_exp[12:0]), .en (m6stg_step), .clk (clk), .q (m3stg_expa[12:0]), .se (se), .si (), .so () ); /////////////////////////////////////////////////////////////////////////////// // // Multiply exponent adder. // // Multiply stage 3. // /////////////////////////////////////////////////////////////////////////////// assign m3stg_expadd[12:0]= (m3stg_expa[12:0] + {6'h3f, m3stg_ld0_inv[6:0]} + 13'h0001); assign m3stg_expadd_eq_0= (&(m3stg_exp[12:0] ^ {6'h3f, m3stg_ld0_inv[6:0]})); assign m3stg_expadd_lte_0_inv= (!(m3stg_expadd[12] || m3stg_expadd_eq_0)); assign m4stg_exp_in[12:0]= (m3stg_expadd[12:0] & {13{(!m3stg_expadd[12])}}); dffe_s #(13) i_m4stg_exp ( .din (m4stg_exp_in[12:0]), .en (m6stg_step), .clk (clk), .q (m4stg_exp[12:0]), .se (se), .si (), .so () ); /////////////////////////////////////////////////////////////////////////////// // // Multiply exponent increment. // // Multiply stage 4. // /////////////////////////////////////////////////////////////////////////////// assign m4stg_exp_plus1[12:0]= m4stg_exp[12:0] + 13'h0001; // Austin update // uarch timing fix // Endpoint: fpu_mul_exp_dp/i_m5stg_exp_pre2_10 // assign m5stg_exp_pre1_in[12:0]= (~({13{m4stg_inc_exp}} // & m4stg_exp_plus1[12:0])); assign m5stg_exp_pre1_in[12:0]= ( ({13{m6stg_step}} & m4stg_exp_plus1[12:0])); dff_s #(13) i_m5stg_exp_pre1 ( .din (m5stg_exp_pre1_in[12:0]), .clk (clk), .q (m5stg_exp_pre1[12:0]), .se (se), .si (), .so () ); // Austin update // uarch timing fix // Endpoint: fpu_mul_exp_dp/i_m5stg_exp_pre2_10 // assign m5stg_exp_pre2_in[12:0]= (~({13{m4stg_inc_exp_inv}} // & m4stg_exp[12:0])); assign m5stg_exp_pre2_in[12:0]= ( ({13{m6stg_step}} & m4stg_exp[12:0])); dff_s #(13) i_m5stg_exp_pre2 ( .din (m5stg_exp_pre2_in[12:0]), .clk (clk), .q (m5stg_exp_pre2[12:0]), .se (se), .si (), .so () ); assign m5stg_exp_pre3_in[12:0]= (~({13{(!m6stg_step)}} & m5stg_expa[12:0])); dff_s #(13) i_m5stg_exp_pre3 ( .din (m5stg_exp_pre3_in[12:0]), .clk (clk), .q (m5stg_exp_pre3[12:0]), .se (se), .si (), .so () ); // Austin update // uarch timing fix // Endpoint: fpu_mul_exp_dp/i_m5stg_exp_pre2_10 //assign m5stg_exp[12:0]= (~m5stg_exp_pre1[12:0]) // | (~m5stg_exp_pre2[12:0]) // | (~m5stg_exp_pre3[12:0]); dff_s #(5) i_m5stg_inc_exp ( .din ({m4stg_shl_55,m4stg_shl_54, m4stg_inc_exp_54,m4stg_inc_exp_55,m4stg_inc_exp_105}), .clk (clk), .q ({m5stg_shl_55,m5stg_shl_54, m5stg_inc_exp_54,m5stg_inc_exp_55,m5stg_inc_exp_105}), .se (se), .si (), .so () ); assign m5stg_exp[12:0] = ( {13{((m5stg_shl_54 & m5stg_inc_exp_54) | (m5stg_shl_55 & m5stg_inc_exp_55) | (m5stg_inc_exp_105) )}} & m5stg_exp_pre1[12:0]) | (~{13{((m5stg_shl_54 & m5stg_inc_exp_54) | (m5stg_shl_55 & m5stg_inc_exp_55) | (m5stg_inc_exp_105) )}} & m5stg_exp_pre2[12:0]) | ~(m5stg_exp_pre3[12:0]); assign m5stg_expa[12:0]= m5stg_exp[12:0]; /////////////////////////////////////////////////////////////////////////////// // // Multiply rounding. // Multiply stage 5. // /////////////////////////////////////////////////////////////////////////////// assign m5stg_exp_plus1[12:0]= m5stg_expa[12:0] + 13'h0001; assign mul_exp_out_in[10:0]= ({11{(mul_exp_out_exp_plus1 && m5stg_fracadd_cout)}} & m5stg_exp_plus1[10:0]) | ({11{mul_exp_out_exp}} & m5stg_expa[10:0]) | ({11{((!m5stg_fracadd_cout) && (!m5stg_in_of))}} & m5stg_expa[10:0]) | ({11{m5stg_in_of}} & {{3{m5stg_fmuld}}, 7'h7f, m5stg_to_0_inv}); dffe_s #(11) i_mul_exp_out ( .din (mul_exp_out_in[10:0]), .en (m6stg_step), .clk (clk), .q (mul_exp_out[10:0]), .se (se), .si (), .so () ); endmodule