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

Subversion Repositories sparc64soc

[/] [sparc64soc/] [trunk/] [T1-FPU/] [fpu_div_frac_dp.v] - Rev 3

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

// ========== Copyright Header Begin ==========================================
// 
// OpenSPARC T1 Processor File: fpu_div_frac_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 ============================================
///////////////////////////////////////////////////////////////////////////////
//
//	Divide pipeline fraction datapath.
//
///////////////////////////////////////////////////////////////////////////////
 
 
module fpu_div_frac_dp (
	inq_in1,
	inq_in2,
	d1stg_step,
	div_norm_frac_in1_dbl_norm,
	div_norm_frac_in1_dbl_dnrm,
	div_norm_frac_in1_sng_norm,
	div_norm_frac_in1_sng_dnrm,
	div_norm_frac_in2_dbl_norm,
	div_norm_frac_in2_dbl_dnrm,
	div_norm_frac_in2_sng_norm,
	div_norm_frac_in2_sng_dnrm,
	div_norm_inf,
	div_norm_qnan,
	d1stg_dblop,
	div_norm_zero,
	d1stg_snan_dbl_in1,
	d1stg_snan_sng_in1,
	d1stg_snan_dbl_in2,
	d1stg_snan_sng_in2,
	d3stg_fdiv,
	d6stg_fdiv,
	d6stg_fdivd,
	d6stg_fdivs,
	div_frac_add_in2_load,
	d6stg_frac_out_shl1,
	d6stg_frac_out_nosh,
	d4stg_fdiv,
	div_frac_add_in1_add,
	div_frac_add_in1_load,
	d5stg_fdivb,
	div_frac_out_add_in1,
	div_frac_out_add,
	div_frac_out_shl1_dbl,
	div_frac_out_shl1_sng,
	div_frac_out_of,
	d7stg_to_0,
	div_frac_out_load,
	fdiv_clken_l,
	rclk,
 
	div_shl_cnt,
	d6stg_frac_0,
	d6stg_frac_1,
	d6stg_frac_2,
	d6stg_frac_29,
	d6stg_frac_30,
	d6stg_frac_31,
	div_frac_add_in1_neq_0,
	div_frac_add_52_inv,
	div_frac_add_52_inva,
	div_frac_out_54_53,
	div_frac_outa,
 
	se,
	si,
	so
);
 
 
input [54:0]	inq_in1;		// request operand 1 to op pipes
input [54:0]	inq_in2;		// request operand 2 to op pipes
input		d1stg_step;		// divide pipe load
input		div_norm_frac_in1_dbl_norm; // select line to div_norm
input		div_norm_frac_in1_dbl_dnrm; // select line to div_norm
input		div_norm_frac_in1_sng_norm; // select line to div_norm
input		div_norm_frac_in1_sng_dnrm; // select line to div_norm
input		div_norm_frac_in2_dbl_norm; // select line to div_norm
input		div_norm_frac_in2_dbl_dnrm; // select line to div_norm
input		div_norm_frac_in2_sng_norm; // select line to div_norm
input		div_norm_frac_in2_sng_dnrm; // select line to div_norm
input		div_norm_inf;		// select line to div_norm
input		div_norm_qnan;		// select line to div_norm
input		d1stg_dblop;		// double precision operation- d1 stg
input		div_norm_zero;		// select line to div_norm
input		d1stg_snan_dbl_in1;	// operand 1 is double signalling NaN
input		d1stg_snan_sng_in1;	// operand 1 is single signalling NaN
input		d1stg_snan_dbl_in2;	// operand 2 is double signalling NaN
input		d1stg_snan_sng_in2;	// operand 2 is single signalling NaN
input		d3stg_fdiv;		// divide operation- divide stage 3
input		d6stg_fdiv;		// divide operation- divide stage 6
input		d6stg_fdivd;		// divide double- divide stage 6
input		d6stg_fdivs;		// divide single- divide stage 6
input		div_frac_add_in2_load;	// load enable to div_frac_add_in2
input		d6stg_frac_out_shl1;	// select line to d6stg_frac
input		d6stg_frac_out_nosh;	// select line to d6stg_frac
input		d4stg_fdiv;		// divide operation- divide stage 4
input		div_frac_add_in1_add;	// select line to div_frac_add_in1
input		div_frac_add_in1_load;	// load enable to div_frac_add_in1
input		d5stg_fdivb;		// divide operation- divide stage 5
input		div_frac_out_add_in1;	// select line to div_frac_out
input		div_frac_out_add;	// select line to div_frac_out
input		div_frac_out_shl1_dbl;	// select line to div_frac_out
input		div_frac_out_shl1_sng;	// select line to div_frac_out
input		div_frac_out_of;	// select line to div_frac_out
input		d7stg_to_0;		// result to max finite on overflow
input		div_frac_out_load;	// load enable to div_frac_out
input		fdiv_clken_l;           // div pipe clk enable - asserted low
input		rclk;		// global clock
 
output [5:0]	div_shl_cnt;		// divide left shift amount
output		d6stg_frac_0;		// divide fraction[0]- intermediate val
output		d6stg_frac_1;		// divide fraction[1]- intermediate val
output		d6stg_frac_2;		// divide fraction[2]- intermediate val
output		d6stg_frac_29;		// divide fraction[29]- intermediate val
output		d6stg_frac_30;		// divide fraction[30]- intermediate val
output		d6stg_frac_31;		// divide fraction[31]- intermediate val
output		div_frac_add_in1_neq_0;	// div_frac_add_in1 != 0
output		div_frac_add_52_inv;	// div_frac_add bit[52] inverted
output		div_frac_add_52_inva;	// div_frac_add bit[52] inverted copy
output [1:0]  	div_frac_out_54_53;	// divide fraction output
output [51:0]	div_frac_outa;		// divide fraction output- buffered copy
 
input           se;                     // scan_enable
input           si;                     // scan in
output          so;                     // scan out
 
 
wire [54:0]	div_frac_in1;
wire [54:0]	div_frac_in2;
wire [52:0]	div_norm_inv_in;
wire [52:0]	div_norm_inv;
wire [52:0]	div_norm;
wire [5:0]	div_lead0;
wire [5:0]	div_shl_cnt;
wire [5:0]	div_shl_cnta;
wire [52:0]	div_shl_data;
wire [105:53]	div_shl_tmp;
wire [52:0]	div_shl;
wire [54:0]	div_shl_save;
wire [54:0]	div_frac_add_in2_in;
wire [54:0]	div_frac_add_in2;
wire [53:0]	d6stg_frac;
wire		d6stg_frac_0;
wire		d6stg_frac_1;
wire		d6stg_frac_2;
wire		d6stg_frac_29;
wire		d6stg_frac_30;
wire		d6stg_frac_31;
wire [54:0]	div_frac_add_in1_in;
wire [54:0]	div_frac_add_in1;
wire [54:0]	div_frac_add_in1a;
wire		div_frac_add_in1_neq_0;
wire [54:0]	div_frac_add;
wire		div_frac_add_52_inv;
wire		div_frac_add_52_inva;
wire [54:0]	div_frac_out_in;
wire  [1:0]     div_frac_out_54_53;
wire [54:0]	div_frac_out;
wire [51:0]	div_frac_outa;
 
 
wire se_l;
 
assign se_l = ~se;
 
clken_buf  ckbuf_div_frac_dp (
  .clk(clk),
  .rclk(rclk),
  .enb_l(fdiv_clken_l),
  .tmb_l(se_l)
  );
 
///////////////////////////////////////////////////////////////////////////////
//
//	Divide fraction inputs.
//
///////////////////////////////////////////////////////////////////////////////
 
dffe_s #(55) i_div_frac_in1 (
	.din	(inq_in1[54:0]),
	.en	(d1stg_step),
	.clk    (clk),
 
        .q      (div_frac_in1[54:0]),
 
	.se     (se),
        .si     (),
        .so     ()
);
 
dffe_s #(55) i_div_frac_in2 (
        .din    (inq_in2[54:0]),
        .en     (d1stg_step),
        .clk    (clk),
 
        .q      (div_frac_in2[54:0]),
 
        .se     (se),
        .si     (),
        .so     ()
);
 
 
///////////////////////////////////////////////////////////////////////////////
//
//      Divide normalization and special input injection.
//
///////////////////////////////////////////////////////////////////////////////
 
assign div_norm_inv_in[52:0]= (~(({53{div_norm_frac_in1_dbl_norm}}
			    & {1'b1, (div_frac_in1[51] || d1stg_snan_dbl_in1),
				div_frac_in1[50:0]})
		| ({53{div_norm_frac_in1_dbl_dnrm}}
			    & {div_frac_in1[51:0], 1'b0})
		| ({53{div_norm_frac_in1_sng_norm}}
			    & {1'b1, (div_frac_in1[54] || d1stg_snan_sng_in1),
				div_frac_in1[53:32], 29'b0})
		| ({53{div_norm_frac_in1_sng_dnrm}}
			    & {div_frac_in1[54:32], 30'b0})
		| ({53{div_norm_frac_in2_dbl_norm}}
			    & {1'b1, (div_frac_in2[51] || d1stg_snan_dbl_in2),
				div_frac_in2[50:0]})
		| ({53{div_norm_frac_in2_dbl_dnrm}}
			    & {div_frac_in2[51:0], 1'b0})
		| ({53{div_norm_frac_in2_sng_norm}}
			    & {1'b1, (div_frac_in2[54] || d1stg_snan_sng_in2),
				div_frac_in2[53:32], 29'b0})
		| ({53{div_norm_frac_in2_sng_dnrm}}
			    & {div_frac_in2[54:32], 30'b0})
		| ({53{div_norm_inf}}
			    & 53'h10000000000000)
		| ({53{div_norm_qnan}}
			    & {24'hffffff, {29{d1stg_dblop}}})
		| ({53{div_norm_zero}}
			    & 53'h00000000000000)));
 
dff_s #(53) i_div_norm_inv (
	.din	(div_norm_inv_in[52:0]),
	.clk	(clk),
 
	.q	(div_norm_inv[52:0]),
 
	.se     (se),
        .si     (),
        .so     ()
);
 
assign div_norm[52:0]= (~div_norm_inv);
 
 
///////////////////////////////////////////////////////////////////////////////
//
//	Divide lead zero count.
//
///////////////////////////////////////////////////////////////////////////////
 
 
fpu_cnt_lead0_53b i_div_lead0 (
	.din	(div_norm[52:0]),
 
	.lead0 (div_lead0[5:0])
);
 
dff_s #12 i_dstg_xtra_regs (
        .din    ({div_lead0[5:0], div_lead0[5:0]}),
        .clk    (clk),
 
        .q      ({div_shl_cnta[5:0], div_shl_cnt[5:0]}),
 
        .se     (se),
        .si     (),
        .so     ()
);
 
 
///////////////////////////////////////////////////////////////////////////////
//
//      Divide left shift.
//
///////////////////////////////////////////////////////////////////////////////
 
dff_s #(53) i_div_shl_data (
	.din	(div_norm[52:0]),
	.clk    (clk),
 
        .q      (div_shl_data[52:0]),
 
	.se     (se),
        .si     (),
        .so     ()
);
 
//assign div_shl_tmp[105:0]= {div_shl_data[52:0], 53'b0} << div_shl_cnta[5:0];
  assign div_shl_tmp[105:53]= div_shl_data[52:0]         << div_shl_cnta[5:0];
 
assign div_shl[52:0]= div_shl_tmp[105:53];
 
dffe_s #(55) i_div_shl_save (
	.din	({2'b0, div_shl[52:0]}),
	.en	(d3stg_fdiv),
        .clk    (clk),
 
        .q      (div_shl_save[54:0]),
 
        .se     (se),
        .si     (),
        .so     ()
);
 
assign div_frac_add_in2_in[54:0]= ({55{d4stg_fdiv}}
			    & (~{2'b0, div_shl[52:0]}))
		| ({55{d6stg_fdiv}}
			    & {25'b0, d6stg_fdivs, 28'b0, d6stg_fdivd});
 
dffe_s #(55) i_div_frac_add_in2 (
	.din	(div_frac_add_in2_in[54:0]),
	.en	(div_frac_add_in2_load),
	.clk    (clk),
 
        .q      (div_frac_add_in2[54:0]),
 
	.se     (se),
        .si     (),
        .so     ()
);
 
 
///////////////////////////////////////////////////////////////////////////////
//
//      Divide adder/subtractor 2nd input.
//
///////////////////////////////////////////////////////////////////////////////
 
assign d6stg_frac[53:0]= ({54{d6stg_frac_out_shl1}}
			    & {div_frac_out[52:0], 1'b0})
		| ({54{d6stg_frac_out_nosh}}
			    & div_frac_out[53:0]);
 
assign d6stg_frac_0= d6stg_frac[0];
assign d6stg_frac_1= d6stg_frac[1];
assign d6stg_frac_2= d6stg_frac[2];
assign d6stg_frac_29= d6stg_frac[29];
assign d6stg_frac_30= d6stg_frac[30];
assign d6stg_frac_31= d6stg_frac[31];
 
assign div_frac_add_in1_in[54:0]= ({55{d4stg_fdiv}}
			    & div_shl_save[54:0])
		| ({55{(div_frac_add_in1_add && (!div_frac_add[54]))}}
			    & {div_frac_add[53:0], 1'b0})
		| ({55{(div_frac_add_in1_add && div_frac_add[54])}}
			    & {div_frac_add_in1[53:0], 1'b0})
		| ({55{d6stg_fdiv}}
			    & {3'b0, d6stg_frac[53:31],
				(d6stg_frac[30:2] & {29{d6stg_fdivd}})});
 
dffe_s #(55) i_div_frac_add_in1 (
	.din	(div_frac_add_in1_in[54:0]),
	.en	(div_frac_add_in1_load),
	.clk    (clk),
 
        .q      (div_frac_add_in1[54:0]),
 
	.se     (se),
        .si     (),
        .so     ()
);
 
dffe_s #(55) i_div_frac_add_in1a (
	.din	(div_frac_add_in1_in[54:0]),
	.en	(div_frac_add_in1_load),
	.clk	(clk),
 
	.q	(div_frac_add_in1a[54:0]),
 
	.se	(se),
	.si	(),
	.so	()
);
 
assign div_frac_add_in1_neq_0= (|div_frac_add_in1[54:0]);
 
 
///////////////////////////////////////////////////////////////////////////////
//
//      Divide adder/subtractor.
//
///////////////////////////////////////////////////////////////////////////////
 
assign div_frac_add[54:0]= (div_frac_add_in1a[54:0]
			+ div_frac_add_in2[54:0]
			+ {54'b0, d5stg_fdivb});
 
assign div_frac_add_52_inv= (!div_frac_add[52]);
assign div_frac_add_52_inva= (!div_frac_add[52]);
 
assign div_frac_out_in[54:0]= ({55{d4stg_fdiv}}
			    & 55'b0)
		| ({55{div_frac_out_add_in1}}
			    & div_frac_add_in1[54:0])
		| ({55{div_frac_out_add}}
			    & div_frac_add[54:0])
		| ({55{div_frac_out_shl1_dbl}}
			    & {div_frac_out[53:0], (!div_frac_add[54])})
		| ({55{div_frac_out_shl1_sng}}
			    & {div_frac_out[53:29], (!div_frac_add[54]), 29'b0})
		| ({55{div_frac_out_of}}
			    & {55{d7stg_to_0}});
 
dffe_s #(55) i_div_frac_out (
	.din	(div_frac_out_in[54:0]),
	.en	(div_frac_out_load),
	.clk    (clk),
 
        .q      (div_frac_out[54:0]),
 
	.se     (se),
        .si     (),
        .so     ()
);
 
assign div_frac_out_54_53[1:0] = div_frac_out[54:53];
 
assign div_frac_outa[51:0]= div_frac_out[51:0];
 
endmodule
 
 
 

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

powered by: WebSVN 2.1.0

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