HierarchyFilesModulesSignalsTasksFunctionsHelp

/******************************************************************************/ 
/*                                                                            */ 
/* Copyright (c) 1999 Sun Microsystems, Inc. All rights reserved.             */ 
/*                                                                            */ 
/* The contents of this file are subject to the current version of the Sun    */ 
/* Community Source License, microSPARCII ("the License"). You may not use    */ 
/* this file except in compliance with the License.  You may obtain a copy    */ 
/* of the License by searching for "Sun Community Source License" on the      */ 
/* World Wide Web at http://www.sun.com. See the License for the rights,      */ 
/* obligations, and limitations governing use of the contents of this file.   */ 
/*                                                                            */ 
/* Sun Microsystems, Inc. has intellectual property rights relating to the    */ 
/* technology embodied in these files. In particular, and without limitation, */ 
/* these intellectual property rights may include one or more U.S. patents,   */ 
/* foreign patents, or pending applications.                                  */ 
/*                                                                            */ 
/* Sun, Sun Microsystems, the Sun logo, all Sun-based trademarks and logos,   */ 
/* Solaris, Java and all Java-based trademarks and logos are trademarks or    */ 
/* registered trademarks of Sun Microsystems, Inc. in the United States and   */ 
/* other countries. microSPARC is a trademark or registered trademark of      */ 
/* SPARC International, Inc. All SPARC trademarks are used under license and  */ 
/* are trademarks or registered trademarks of SPARC International, Inc. in    */ 
/* the United States and other countries. Products bearing SPARC trademarks   */ 
/* are based upon an architecture developed by Sun Microsystems, Inc.         */ 
/*                                                                            */ 
/******************************************************************************/ 
//  @(#)stat_ctl.v	1.16  2/21/93
//
// **************************************************************
//  High-level verilog model of STATus control
//
//  This module contains FSR and tracks the mode of the FPU.
//
// **************************************************************

[Up: fpc_ctl statctl1]
module stat_ctl (ss_clock, ss_reset, fold_annul_e, ext_flush, fpm_inx, fpstat,
		 fsr_data_in, fq_qne_0, fq_empty_next, qne, qne_r,
		 fq_started_0, fq_type_0, fcmp_q0,
		 done_q0, writeback_q0, unfin_fsmuld, fsr_ld_nh,
		 ext_hold, ext_fxack, fstore_w, stdfq_e, stdfq_w,
		 stdfq_r_noexc, dir_finst_nostore,
		 fsr_out, notrap_writeback, ext_fexc, exemode, exemode_two,
		 ss_scan_mode);

input	ss_clock,		// Clock input
	ss_reset,		// FPU reset
	ext_flush,		// FPU flush (IU trap)
	fold_annul_e,		// inst in E is annuled
	fpm_inx ;		// mul inexact signal
input [7:0] fpstat;		// Meiko status bus
input [18:0] fsr_data_in;	// Output of Load Data Register (ldh):
				//   {ldh[31:30], ldh[27:23], ldh[11:0]}
input	fq_qne_0,		// fq0 not empty
	fq_empty_next,		// only 1 entry used
	qne,			// Q not empty present state bit
	qne_r,			// indicates FPop has at least reached R-stage
	fq_started_0,		// launch status of fq0
	fq_type_0,		// type of fq0 (1=mul, 0=meiko)
	fcmp_q0,		// valid FCMP instr. in QI reg.
	done_q0,		// FPop in q0 (if any) has finished
	writeback_q0,		// result writeback signal
	unfin_fsmuld,		// unfinished fsmuld
	fsr_ld_nh,		// FSR load enable (requires "& ~ext_hold" )
	ext_hold,		// IU pipeline held (frozen) from mhold, etc.
	ext_fxack,		// FPU exception acknowledge-without hold term
	fstore_w,		// FP store in W-stage
	stdfq_e,		// stdfq in E-stage
	stdfq_w,		// stdfq in W-stage
	stdfq_r_noexc,		// stdfq in R-stage, no data access exception;
				// only instr. to allow exit from excmode
	dir_finst_nostore,	// non-store FP instruction in decode
	ss_scan_mode;

output [22:0] fsr_out;		// FPU status reg output (non-constant bits)
output	notrap_writeback,	// writeback q0 if no fpu exception
	ext_fexc,		// External fexc signal to IU
	exemode,		// execute mode
	exemode_two;		// exemode delayed 2 cycles

wire fptrap ;

	// FSR fields
wire  [4:0]  fsr_cexc;
wire  [4:0]  fsr_aexc;
wire  [1:0]  fsr_cc;
wire  [2:0]  fsr_ftt;
wire  [4:0]  fsr_tem;
wire  [1:0]  fsr_rd;

	// States: EXECUTION/EXCEPTION_PENDING/EXCEPTION_ACKNOWLEDGED
wire  exemode, exemode_one, exemode_two, pendmode, excmode ;


	// *******************************************************
wire reset_l = ~ss_reset ;

	// resetflush   = (~ext_hold & ext_flush) | ss_reset;
	// resetflush_l = (ext_hold | ~ext_flush) & ~ss_reset;
ME_O2A1 iu_hold_gate_1 (.a( ext_hold ), .b( ~ext_flush ), .c( reset_l ),
			.z( resetflush_l ) );

	// clear_e   = (~ext_hold & (ext_flush | fold_annul_e)) | ss_reset;
	// clear_e_l = (ext_hold | ~(ext_flush | fold_annul_e)) & ~ss_reset;
ME_O2A1 iu_hold_gate_2 (.a( ext_hold ), .b( ~(ext_flush | fold_annul_e) ),
			.c( reset_l ), .z( clear_e_l ) );


	// *******************************************************
	// Pipeline to determine if a non-store FP instruction is in
	// the IU's pipeline
ME_FDS2LP finst_ff_e(.q(finst_nostore_e), .cp(ss_clock), .cr(resetflush_l),
			.ld(~ext_hold),	.d(dir_finst_nostore));

ME_FDS2LP finst_ff_w(.q(finst_nostore_w), .cp(ss_clock), .cr(clear_e_l),
			.ld(~ext_hold),	.d(finst_nostore_e));


	// Sequence error detection
wire seq_err = excmode & finst_nostore_w ;

	// Original logic equations:
	//
	//wire ipendmode = ( (pendmode & ~(ext_fxack & ~ext_hold)) |
	//		   (seq_err & ~ext_flush & ~ext_hold) |
	//		   (fptrap & exemode & exemode_two & fq_started_0)
	//		 ) & fq_qne_0 ;
	//
	//wire iexcmode = (pendmode & ext_fxack & ~ext_hold) |
	//		( ~(((stdfq_w & fq_empty_next) | seq_err) &
	//			~ext_flush & ~ext_hold) &
	//		  excmode
	//		) ;
	//
	//wire iexemode = ~(iexcmode | ipendmode) ;

	// Hand-structured equations:
	// ----------------------------------------
	// ipendmode = (ipendmode_x & ext_hold) | (ipendmode_y & ~ext_hold) |
	//		ipendmode_z;
wire ipendmode_x = pendmode & fq_qne_0 ;
wire ipendmode_y = seq_err & ~ext_flush & fq_qne_0 ;
wire ipendmode_z = ( (pendmode & ~ext_fxack) |
		     (fptrap & exemode & exemode_two & fq_started_0)
		   ) & fq_qne_0 ;

ME_AI22O1_C iu_hold_gate_3 (.a1( ipendmode_y ), .a2( ext_hold ),
			    .b1( ipendmode_x ), .b2( ext_hold ),
			    .c( ipendmode_z ), .z( ipendmode ) );


	// ----------------------------------------
	// iexcmode = (iexcmode_x & ext_hold) | (iexcmode_y & ~ext_hold) |
	//		iexcmode_z;
wire iexcmode_x = excmode ;
wire iexcmode_y = pendmode & ext_fxack ;
wire iexcmode_z = ~(((stdfq_w & fq_empty_next) | seq_err) & ~ext_flush) &
		  excmode ;

ME_AI22O1_C iu_hold_gate_4 (.a1( iexcmode_y ), .a2( ext_hold ),
			    .b1( iexcmode_x ), .b2( ext_hold ),
			    .c( iexcmode_z ), .z( iexcmode ) );


	// ----------------------------------------
wire iexemode_x = ipendmode_x | iexcmode_x ;
wire iexemode_y = ipendmode_y | iexcmode_y ;
wire iexemode_z = ipendmode_z | iexcmode_z ;

ME_O22A1 iu_hold_gate_5 (.a1(  ext_hold ), .a2( ~iexemode_y ),
			 .b1( ~ext_hold ), .b2( ~iexemode_x ),
			 .c( ~iexemode_z ), .z( iexemode ) );


	// ******* FPC state variables *******
ME_FD1R exemode_ff(.q(exemode), .cp(ss_clock), .cr(reset_l), .d(iexemode));

ME_FD1R penmode_ff(.q(pendmode), .cp(ss_clock), .cr(reset_l), .d(ipendmode));

ME_FD1R excmode_ff(.q(excmode), .cp(ss_clock), .cr(reset_l), .d(iexcmode));

	// delayed versions of exemode used to prevent false traps
ME_FD1P exemode_one_ff (.q(exemode_one), .cp(ss_clock), .d(exemode) );
ME_FD1P exemode_two_ff (.q(exemode_two), .cp(ss_clock), .d(exemode_one) );


//synopsys translate_off
always @ (exemode or pendmode or excmode) begin
	if ( ((exemode + pendmode + excmode) !== 2'b01) &&
	     (~`IU.iuchip.ss_reset && ( $time > 15 )) ) begin
	   $display("### ERROR:  FPU exemode, pendmode, excmode = %d %d %d",
			exemode, pendmode, excmode);
	end
end
//synopsys translate_on


		// generate a special case sequence error for STDFQ when
		// fsr.qne==0; This case is the only immediate fp_exception
		// trap (not deffered) implemented.  This case should only
		// happen when the FPC is in execute mode, and it must
		// stay in execute mode.
wire i_noqne_err = stdfq_e & ((stdfq_r_noexc & fq_empty_next) | ~qne) ;

ME_FDS2LP noqne_ff (.q(noqne_err), .cp(ss_clock), .cr(resetflush_l),
		    .ld(~ext_hold), .d(i_noqne_err) );

wire int_fexc;

	// don't assert fexc until FPop leaves W-stage
	// don't assert fexc when non-dependent fstore is held in W-stage

	// Original logic equation:
	//wire i_fexc = ipendmode & (qne_r | ~ext_hold) &
	//		(int_fexc | ~(fstore_w & ext_hold)) ;

	// Hand-structured equations:
	// ----------------------------------------
wire i_fexc_common = qne_r & (int_fexc | ~fstore_w) ;
wire i_fexc_x = i_fexc_common & ipendmode_x ;
wire i_fexc_y = ipendmode_y | ipendmode_z ;
wire i_fexc_z = i_fexc_common & ipendmode_z ;

ME_AI22O1_C iu_hold_gate_6 (.a1( i_fexc_y ), .a2( ext_hold ),
			   .b1( i_fexc_x ), .b2( ext_hold ),
			   .c( i_fexc_z ), .z( i_fexc ) );


ME_FD1R fexc_ff(.q(int_fexc), .cp(ss_clock), .cr(reset_l), .d(i_fexc));

assign ext_fexc = int_fexc | noqne_err ;


						// select mul or Meiko status
wire [5:0] fpu_status = fq_type_0 ? {4'b0, fpm_inx} : fpstat[5:0] ;

						// fixed ieee_uf.  mn. 12/27/89
wire ieee_uf = fpu_status[2] & (fpu_status[0] | fsr_tem[2]);

wire  [4:0]  cexc = {fpu_status[4:3], ieee_uf, fpu_status[1:0]};
wire  [1:0]  fcc = fpstat[7:6];			// Condition code bits

	// Trap exception 
wire [4:0]  tcexc = cexc & fsr_tem ;
wire ieee_trap = | tcexc ;
wire unimp_trap = fpu_status[5] ;		// mn. 12/12/89
wire unfin_trap = unfin_fsmuld ;
wire fpp_in_trap = ieee_trap | unimp_trap | unfin_trap ;
assign fptrap = fpp_in_trap & fq_qne_0 & done_q0 ;

wire notrap_writeback = writeback_q0 & ~fpp_in_trap ;

	// Accrued exception bits
wire [4:0]  aexc = cexc | fsr_aexc;

	// FSR ENables

	// ftt_en  = writeback_q0  | (seq_err & ~ext_flush & ~ext_hold) |
	//		(noqne_err & ext_fxack & ~ext_hold) ;

wire ftt_en, ftt_en_l ;
wire ftt_en_x = (seq_err & ~ext_flush) | (noqne_err & ext_fxack);
ME_O2A1 iu_hold_gate_7 (.a( ext_hold ), .b( ~ftt_en_x ), .c( ~writeback_q0 ),
			.z( ftt_en_l ) );

assign ftt_en = ~ftt_en_l ;


wire fsr_ld, fsr_ld_l;

ME_OR2_B iu_hold_gate_8 (.a( ext_hold ), .b( ~fsr_ld_nh ), .z( fsr_ld_l ) );
assign fsr_ld = ~fsr_ld_l ;


wire fcc_en, fcc_en_l ;
	// fcc_en  = (notrap_writeback & fcmp_q0) | fsr_ld;

ME_O2A1 iu_hold_gate_9 (.a( ext_hold ), .b( ~fsr_ld_nh ),
			.c( ~(notrap_writeback & fcmp_q0) ), .z( fcc_en_l ) );
assign fcc_en = ~fcc_en_l ;


wire aexc_en, aexc_en_l ;
	// aexc_en = notrap_writeback | fsr_ld; 

ME_O2A1 iu_hold_gate_10 (.a( ext_hold ), .b( ~fsr_ld_nh ),
			 .c( ~notrap_writeback ), .z( aexc_en_l ) );
assign aexc_en = ~aexc_en_l ;


wire cexc_en, cexc_en_l ;
	// cexc_en = (writeback_q0 & ~(unimp_trap | unfin_trap)) | fsr_ld;
wire cexc_en_x = writeback_q0 & ~(unimp_trap | unfin_trap) ;

ME_O2A1 iu_hold_gate_11 (.a( ext_hold ), .b( ~fsr_ld_nh ),
			 .c( ~cexc_en_x ), .z( cexc_en_l ) );
assign cexc_en = ~cexc_en_l;


	// FSR RW Inputs
wire [4:0] hold_4_0 = {5{ext_hold}};		// 5 copies of ext_hold
wire [4:0] fsr_ld_nh_4_0 = {5{fsr_ld_nh}};	// 5 copies of fsr_ld_nh

wire [4:0] icexc ;		// fsr_ld ? fsr_data_in[4:0] : cexc;
wire [4:0] icexc_y =  fsr_ld_nh_4_0[4:0] & fsr_data_in[4:0] ;
wire [4:0] icexc_z = ~fsr_ld_nh_4_0[4:0] & cexc[4:0] ;

ME_AI22O1_C_5 iu_hold_gate_12 ( .a1( icexc_y[4:0] ), .a2( hold_4_0[4:0] ),
				.b1( cexc[4:0] ), .b2( hold_4_0[4:0] ),
				.c( icexc_z[4:0] ), .z( icexc[4:0] ) );


wire [4:0] iaexc ;		// fsr_ld ? fsr_data_in[9:5] : aexc;
wire [4:0] iaexc_y = fsr_ld_nh_4_0[4:0] & fsr_data_in[9:5] ;
wire [4:0] iaexc_z = ~fsr_ld_nh_4_0[4:0] & aexc[4:0] ;

ME_AI22O1_C_5 iu_hold_gate_13 ( .a1( iaexc_y[4:0] ), .a2( hold_4_0[4:0] ),
				.b1( aexc[4:0] ), .b2( hold_4_0[4:0] ),
				.c( iaexc_z[4:0] ), .z( iaexc[4:0] ) );


wire [1:0] ifcc ;		// fsr_ld ? fsr_data_in[11:10] : fcc;
wire [1:0] ifcc_y = fsr_ld_nh_4_0[1:0] & fsr_data_in[11:10] ;
wire [1:0] ifcc_z = ~fsr_ld_nh_4_0[1:0] & fcc[1:0] ;

ME_AI22O1_C_2 iu_hold_gate_14 ( .a1( ifcc_y[1:0] ), .a2( hold_4_0[1:0] ),
				.b1( fcc[1:0] ), .b2( hold_4_0[1:0] ),
				.c( ifcc_z[1:0] ), .z( ifcc[1:0] ) );


wire [4:0] ltem  = fsr_data_in[16:12];
wire [1:0] lrd   = fsr_data_in[18:17];

	// FSR RO Inputs
wire [2:0] iftt = (seq_err | noqne_err) ? 3'h4 :
		      (unimp_trap ? 3'h3 :
			  (unfin_trap ? 3'h2 :
			      (ieee_trap ? 3'h1 : 3'h0)));

	// FSR (FFs)
ME_FDS2LP5 cexc_ff(fsr_cexc,,ss_clock, reset_l, icexc, cexc_en); 
ME_FDS2LP5 aexc_ff(fsr_aexc,,ss_clock, reset_l, iaexc, aexc_en); 
ME_FDS2LP5 tem_ff (fsr_tem,, ss_clock, reset_l, ltem,  fsr_ld); 
ME_FDS2LP2 rd_ff  (fsr_rd,,  ss_clock, reset_l, lrd,   fsr_ld); 
ME_FDS2LP3 ftt_ff (fsr_ftt,, ss_clock, reset_l, iftt,  ftt_en); 
ME_FDS2LP2 fcc_ff (fsr_cc,,  ss_clock, reset_l, ifcc,  fcc_en); 

ME_BUFF b0 (qne, fsr_qne);

	// non-constant FSR bits
wire [22:0] fsr_out = {fsr_rd, fsr_tem, fsr_ftt, fsr_qne, fsr_cc,
			fsr_aexc, fsr_cexc};

// ***************************** simulation code ************************
//synopsys translate_off

ME_TIEOFF toff (HI,LO);

				// Constant bits
ME_INVA g0 (HI, res29);		// FSR[29:28] ==> unused
ME_INVA g1 (HI, res28);
ME_INVA g2 (HI, res22);		// FSR[22] ==> NS bit unused for Meiko
ME_INVA g3 (HI, res21);		// FSR[21:20] ==> reserved
ME_INVA g4 (HI, res20);
ME_INVA g5 (LO, res19);		// FSR[19:17] ==> ver# = 4
ME_INVA g6 (HI, res18);
ME_INVA g7 (HI, res17);
ME_INVA g8 (HI, res12);		// FSR[12] ==> unused

wire [1:0] res3 = {res29, res28};
wire [5:0] res2 = {res22, res21, res20, res19, res18, res17};

wire [31:0] fsr = {fsr_rd, res3, fsr_tem, res2, fsr_ftt, fsr_qne, res12,
		   fsr_cc, fsr_aexc, fsr_cexc};

//synopsys translate_on

endmodule
HierarchyFilesModulesSignalsTasksFunctionsHelp

This page: Created:Thu Aug 19 11:59:24 1999
From: ../../../sparc_v8/ssparc/fpu/fp_fpc/rtl/stat_ctl.v

Verilog converted to html by v2html 5.0 (written by Costas Calamvokis).Help