HierarchyFilesModulesSignalsTasksFunctionsHelp
123

/******************************************************************************/ 
/*                                                                            */ 
/* 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.         */ 
/*                                                                            */ 
/******************************************************************************/ 
/***************************************************************************
****************************************************************************
***
***  Program File:  @(#)pc_cntl.v
***
***
****************************************************************************
****************************************************************************/
// @(#)pc_cntl.v	1.154 4/8/94
// pc_cntl.v

/*
	Program Counter Control Logic
*/


[Up: Mdecode pc_cntl]
module Mpc_cntl (
	// OUTPUTS
	sel_lta_fpc,
	sel_idpc_fpc,
	sel_post_reset,
	sel_p_fpc,
	sel_alt_tag,
	sel_i1pfpc_fpc,
	sel_i2dpc_fpc,
	fetch_ic_even,
	fetch_ic_odd,
	fetch_TOQ,
	fetch_alt,
	fetch_SIQ,
	ncant_unload,
	hold_alt,

	fold_annul,
	fold_annul2,
	fold_annul3,
	fold_annul4,
	fold_annul5,
	fold_annul6,
	fold_annul7,

	nfold_annul,
	mispredicted,
	untaken_empty_ilock,
	sv_rest_fold_ilock,
	sv_rest_recirc,
	sel_shift1,
	sel_shift2,
	sel_shift3,
	sel_fold1,
	sel_fold2,
	sel_even1,
	sel_odd1,
	hold_q1,
	sel_even2,
	sel_odd2,
	hold_q2,
	sel_even3,
	sel_odd3,
	hold_q3,
	hold_q4,
	sel_last_gen,
	recirc2_default,
	sel_inc_ll_gen,
	sel_inc_dpc,
	sel_inc_alttag,
	sel_gpc,
	sel_recirc,
	sel_recirc_inc,
	sel_lgen_iva,
	sel_gpc_ic,
	sel_recirc_ic,
	sel_recirc_inc_ic,
	sadr_zero_ic,
	force_ifill,
	flush_ic_e,
	force_dva,
	fwd_wpc,
	use_tpc,
	fwd_tpcm4,
	lta_hold,
	dbr_cond,
	hld_car_mar,
	hld_lgens,
	hld_backup,
	take_icdata,
	sel_old_aa,
	hld_dir2,
	sel_lgen_ica,
	stop_fetch,
	did_fetch,

	// INPUTS
	nANNUL,
	s,
	fcc_taken,
	bicc_taken,
	d_hop3,
	e_opcode_hi,
	w_hop3,
	iu_fetch_f,
	gen_help,
	gen_help_op,
	nfold_taken,
	IU_in_trap,
	TRAP,
	ER_SDOUT,
	trap_cyc1,
	trap_cyc2,
	fpc_low,
	nlta_low,
	ndpc_low,
	nalttag_low,
	iacc_exc_mmumiss_d,
	d_nop,
	d_trap,
	fcc_ilock,
	sadr_jmprett,
	sadr_tbr,
	sadr_zero,
	toq_entry_bits,
	nq1_entry_hi,
	iexc_for_br,
	niexc1_hi,
	ilock,
	valid_decode,
	valid_decode_nilock,
	hold_noic,
	hold_ic,
	iu_asi_e_4,
	ic_force_ifill_g,
	mm_istat_avail,
	i_dva_req,
	iwait_f,
	dwait_w_for_flush,
//	extend_tag_miss,
	enbl_br_fold,
	start_itag_inv,
	q3_iae, q3_ptc, q2_iae, q2_ptc, q1_iae, q1_ptc,
	hnop_into_ex,
	wo_trap_w, wu_trap_w,

	// MISC
	ss_clock,
	hold,
	reset,
	del_resetm
);

output sel_lta_fpc;
output sel_idpc_fpc;
output sel_post_reset;
output sel_p_fpc;
output sel_alt_tag;
output sel_i1pfpc_fpc;
output sel_i2dpc_fpc;
output fetch_ic_even;
output fetch_ic_odd;
output fetch_TOQ;
output fetch_alt;
output fetch_SIQ;
output ncant_unload;
output hold_alt;

output fold_annul;
output fold_annul2;
output fold_annul3;
output fold_annul4;
output fold_annul5;
output fold_annul6;
output fold_annul7;

output nfold_annul;
output mispredicted;
output untaken_empty_ilock;
output sv_rest_fold_ilock;
output sv_rest_recirc;
output sel_shift1;
output sel_shift2;
output sel_shift3;
output sel_fold1;
output sel_fold2;
output sel_even1;
output sel_odd1;
output hold_q1;
output sel_even2;
output sel_odd2;
output hold_q2;
output sel_even3;
output sel_odd3;
output hold_q3;
output hold_q4;
output sel_last_gen;
// output sel_ll_gen;
// output sel_inc_last_gen;
output recirc2_default;
output sel_inc_ll_gen;
output sel_inc_dpc;
output sel_inc_alttag;
output sel_gpc;
output sel_recirc;
output sel_recirc_inc;
output sel_lgen_iva;
output sel_gpc_ic;
output sel_recirc_ic;
output sel_recirc_inc_ic;
output sadr_zero_ic;
output force_ifill;
output flush_ic_e;
output force_dva;
// output sadr_fold_aa;
output fwd_wpc;
output use_tpc;
output fwd_tpcm4;
output lta_hold;
output [3:0] dbr_cond;
output hld_car_mar;
output hld_lgens;
output hld_backup;
output take_icdata;
output sel_old_aa;
output hld_dir2;
output sel_lgen_ica;
output stop_fetch;
output did_fetch;

input nANNUL;
input s;
input fcc_taken;
input bicc_taken;
input [8:0] d_hop3;
input [10:2] e_opcode_hi;
input [8:0] w_hop3;
input iu_fetch_f;
input gen_help;
input gen_help_op;
input nfold_taken;
input IU_in_trap;
input TRAP;
input ER_SDOUT;
input trap_cyc1;
input trap_cyc2;
input fpc_low;
input nlta_low;
input ndpc_low;
input nalttag_low;
input iacc_exc_mmumiss_d;
input d_nop;
input d_trap;
input fcc_ilock;
input sadr_jmprett;
input sadr_tbr;
input sadr_zero;
input [31:22] toq_entry_bits;
input [31:22] nq1_entry_hi;
input [10:2] iexc_for_br;
input [10:2] niexc1_hi;
input ilock;
input valid_decode;
input valid_decode_nilock;
input hold_noic;
input hold_ic;
input iu_asi_e_4;
input ic_force_ifill_g;
input mm_istat_avail;
input i_dva_req;
input iwait_f;
input dwait_w_for_flush;
// input extend_tag_miss;
input enbl_br_fold;
input start_itag_inv;
input q3_iae, q3_ptc, q2_iae, q2_ptc, q1_iae, q1_ptc;
input hnop_into_ex;
input wo_trap_w;
input wu_trap_w;

input ss_clock;
input hold;
input reset;
input del_resetm;


// FORWARD DECLARATIONS

	wire [4:0] q_state;
	wire sequential_f;
	wire fold_in_d;
	wire fold_in_e;
	wire last_predict_taken;
	wire fwd_wpc_almost;
	wire trap_before_fold;
	wire keep_alt;
	wire last_force_dva;
	wire last_can_fold;
	wire mispredicted;
	wire sel_post_reset;
	wire kill_fetch_fill;

	wire [8:0] e_hop3 = e_opcode_hi[10:2];
	wire [2:0] d_hop = d_hop3[8:6];
	wire [5:0] d_hop2 = d_hop3[8:3];
	wire [2:0] e_hop = e_hop3[8:6];
	wire [5:0] e_hop2 = e_hop3[8:3];

//	wire br_in_e = e_hop2==BICC;
//	wire fbr_in_e = e_hop2==BFCC;
//	wire br_fbr_in_e = br_in_e | fbr_in_e;
//	wire call_in_e = e_hop==CALL;
//	wire rett_in_e = e_hop3==RETT;
//	wire jmp_in_e = (e_hop3==JMP);

	wire hld_llc;
	wire part_stuff_q;
	wire hld_car_mar;

	wire last_taken;
//	wire last_taken;
	wire sv_rest_recirc;
	wire kill_jmp_ld;
	wire cant_unload;
	wire untaken_empty_ilock;
	wire fetch_alt;
	wire force_ifill;
	wire force_dva;
	wire nkill_jmp_ld;
	wire fld_hlp_misp;
	wire nmispredicted;
	wire [4:0] nq_state;
	wire nlast_taken;
	wire ncant_unload;
	wire can_fold;

	wire fold_annul;
	wire fold_annul2;
	wire fold_annul3;
	wire fold_annul4;
	wire fold_annul5;
	wire fold_annul6;
	wire fold_annul7;

	wire flush_asi_e;
	wire hold_alt;
	wire flushq;
	wire hld_dir2;

/******************** some pipeline stuff *********************/

	wire br_in_d = valid_decode_nilock & (d_hop2==`BICC);
	wire fbr_in_d = valid_decode_nilock & (d_hop2==`BFCC);
	wire br_in_dec = br_in_d | fbr_in_d;
	wire br_in_dec_nvd = d_hop2==`BICC | d_hop2==`BFCC;

	wire br_in_d_vd = valid_decode & (d_hop2==`BICC);
	wire fbr_in_d_vd = valid_decode & (d_hop2==`BFCC);

//	REGWIRE br_in_e;
//	REG(br_in_e_reg,1,br_in_e,br_in_d_vd,ss_clock,hold)
//	REGWIRE fbr_in_e;
//	REG(fbr_in_e_reg,1,fbr_in_e,fbr_in_d_vd,ss_clock,hold)

	wire br_fbr_in_d = br_in_d_vd | fbr_in_d_vd;

	wire br_fbr_in_e;
	Mflipflop_1 br_fbr_in_e_reg_1(br_fbr_in_e,br_fbr_in_d,ss_clock,hold) ;

	wire call_in_d = valid_decode_nilock & (d_hop==`CALL);
	wire call_in_d_nvd = d_hop==`CALL;
	wire call_in_d_vd = valid_decode & (d_hop==`CALL);

	wire call_in_e;
	Mflipflop_1 call_in_e_reg_1(call_in_e,call_in_d_vd,ss_clock,hold) ;

	wire jmp_in_d = d_hop3==`JMP;
//	wire njmp_in_e = jmp_in_d & ~hnop_into_ex & ~reset & ~trap_cyc1;
	wire njmp_in_e = jmp_in_d & valid_decode;
	wire jmp_in_e;
	Mflipflop_1 jmp_in_e_reg_1(jmp_in_e,njmp_in_e,ss_clock,hold) ;

	wire njmp_in_w = jmp_in_e & ~fold_annul2 & ~trap_cyc1;

	wire rett_in_d = d_hop3==`RETT;
//	wire nrett_in_e = rett_in_d & ~hnop_into_ex & ~reset & ~trap_cyc1;
	wire nrett_in_e = rett_in_d & valid_decode;
	wire rett_in_e;
	Mflipflop_1 rett_in_e_reg_1(rett_in_e,nrett_in_e,ss_clock,hold) ;

	wire nrett_in_w = rett_in_e & ~fold_annul2 & ~trap_cyc1;

	wire njmp_rett_in_w = nrett_in_w | njmp_in_w;

//	REGWIRE jmp_rett_in_w;
//	REG(jmp_rett_in_w_reg,1,jmp_rett_in_w,njmp_rett_in_w,ss_clock,hold)

//	wire cti_in_e = br_fbr_in_e | call_in_e | jmp_in_w;

/******************** BRANCH FOLDING ********************/

/*
 * check if can fold TOQ
 */
	wire jmp_in_d_nvd =
		  jmp_in_d
		| jmp_in_e
		;
	wire rett_in_d_nvd =
		  rett_in_d
		| rett_in_e
		;

	// this term is used only in can_fold.  it
	// does not include valid_decode_nilock - vdni
	// is in the can_fold equation already

	wire cti_in_d_nvd =
		  br_in_dec_nvd | fold_in_d
		| call_in_d_nvd
		| jmp_in_d_nvd | rett_in_d_nvd
		;

// this term used only for nsequential_f determination - by definition,
// can't be sequential with this on, since target fetch occurs.
	wire cti_in_d_nof =
		  br_in_dec
		| call_in_d
		| e_hop3==`JMP
		| e_hop3==`RETT
		;

	// this stuff was moved from the queue for timing reasons
	// this is the inst_for_br
	wire hold_q1_real = hold_q1 | hold;
	wire [31:22] dum_toq;
	Mflipflop_10 dum_toq_reg_10(dum_toq,nq1_entry_hi,ss_clock,hold_q1_real) ;

	wire hld_dir2_real = hld_dir2 | hold;
	wire [31:22] backup_bdir;
	Mflipflop_10 backup_dir_reg_10(backup_bdir,toq_entry_bits,ss_clock, 		hld_dir2_real) ;

	wire [31:22] new_toq_entry_bits;
    // Expanded macro begin.
    // cmux2(nteb_mux, 10, new_toq_entry_bits,  		dum_toq,  backup_bdir,  cant_unload)
    function [10:1] nteb_mux ;
        input [10:1] in0_fn ;
        input [10:1] in1_fn ;
        input select_fn ;
        reg [10:1] out_fn ;
        begin
            case (select_fn) /* synopsys parallel_case */
                1'b0: out_fn = in0_fn ;
                1'b1: out_fn = in1_fn ;
                default: out_fn = 65'hx;
            endcase
            nteb_mux = out_fn ;
        end
    endfunction
    assign new_toq_entry_bits = nteb_mux( 		dum_toq,  backup_bdir,  cant_unload) ;
    // Expanded macro end.


	wire [4:0] toq_op_op2 =
		{new_toq_entry_bits[31:30],new_toq_entry_bits[24:22]};

	wire br_in_TOQ = toq_op_op2==5'b00_010;		// op_op2 for BICC

 // better check that cti_in_e is correct and isn't too pessimistic
 //  don't need rett in cti_in_e since that would mean a br/rett combo
//	wire looks_seq =
//		fold_in_e & cti_in_e	// & last_predict_taken
//		;
//		  fold_in_e & ~last_predict_taken

//	enable fold now comes from MMU - enbl_br_fold
//	wire enable_fold = 1'b1;	// temp - make scan only reg

	wire ntaken_cti_in_e =
		  nlast_taken
		| call_in_d_vd
		| ~fold_annul2 & (jmp_in_e | rett_in_e)
		;

//	REGWIRE taken_cti_in_e;
//	REG(taken_cti_in_e_reg,1,taken_cti_in_e,ntaken_cti_in_e,ss_clock,hold)

	/*
	wire taken_cti_in_e =
		  last_taken		// indicates taken BICC or BFCC in E
		| call_in_e
		| jmp_in_w
		| rett_in_w
		;
	*/
		// the wrspec_in_pipe term is used to prevent folding cuz S
		// bit may change on wrpsr and don't want to cause problems
		// if ic_sup_only (iexc_for_br[2]) is on.  also, cuz
		// we are guaranteed SPARCness as long as the following
		// 3 instructions are clean with respect to WSpecreg.
		// if we fold, then that 4th inst will appear in the
		// 3rd inst's slot and cause problems.

	wire wrspec_in_d = d_hop3[7:0] == 6'b101100;
			// op=10, top 4 bits of op3
			//    1100 for Write state
			//    register (wrpsr, etc)
	wire nwrspec_in_e = wrspec_in_d & valid_decode;
	wire wrspec_in_e;
	Mflipflop_1 wrspec_in_e_reg_1(wrspec_in_e,nwrspec_in_e,ss_clock,hold) ;
	wire nwrspec_in_w = wrspec_in_e & ~fold_annul2;
	wire wrspec_in_w;
	Mflipflop_1 wrspec_in_w_reg_1(wrspec_in_w,nwrspec_in_w,ss_clock,hold) ;

	wire wrspec_in_pipe =
		  wrspec_in_d | wrspec_in_e | wrspec_in_w
		;

//	wire rett_in_pipe =		// need this term cuz we don't want
//		  d_hop3==RETT		// to fold br if S bit is changing
//		| e_hop3==RETT		// in R cycle of rett in case
//		;			// ic_sup_only (iexc_for_br[2]) and
					// S bit cause a priv trap.
//		| rett_in_w		// already in taken_cti_in_e

	wire d_help = d_hop3[8];


	// don't allow folding if the TOQ had a fetch problem.
	// need to qualify iexc_for_br[2] (ic_sup_only) with
	// s bit.  if s bit is off and ic_sup_only on, the
	// branch cannot folded since it will take a
	// priv trap

	// some of this stuff was moved from the queue for timing
	// reasons.  this is iexc_for_br
	wire [10:2] dum_q1_iexc;
	Mflipflop_9 dum_q1_iexc_reg_9(dum_q1_iexc,niexc1_hi,ss_clock,hold_q1_real) ;

	wire [10:2] backup_biexc;
	Mflipflop_9 backup_biexc_reg_9(backup_biexc,iexc_for_br[10:2], 		ss_clock,hld_dir2_real) ;

	wire [10:2] new_iexc_for_br;
    // Expanded macro begin.
    // cmux2(nifb_mux, 9, new_iexc_for_br,  		dum_q1_iexc, backup_biexc, cant_unload)
    function [9:1] nifb_mux ;
        input [9:1] in0_fn ;
        input [9:1] in1_fn ;
        input select_fn ;
        reg [9:1] out_fn ;
        begin
            case (select_fn) /* synopsys parallel_case */
                1'b0: out_fn = in0_fn ;
                1'b1: out_fn = in1_fn ;
                default: out_fn = 65'hx;
            endcase
            nifb_mux = out_fn ;
        end
    endfunction
    assign new_iexc_for_br = nifb_mux( 		dum_q1_iexc, backup_biexc, cant_unload) ;
    // Expanded macro end.


	wire bad_toq_t1 =
		  new_iexc_for_br[10] | new_iexc_for_br[9]
		| new_iexc_for_br[8] | new_iexc_for_br[7]
		;

	wire bad_toq_t2 =
		  new_iexc_for_br[6] | new_iexc_for_br[5]
		| new_iexc_for_br[4] | new_iexc_for_br[3]
		;

	wire bad_toq_t3 = new_iexc_for_br[2] & ~s;

	wire bad_toq =
		  bad_toq_t1 | bad_toq_t2 | bad_toq_t3
		;

// determine whether the instruction at TOQ can be folded.
// use some pipelining to reduce the logic where possible.

	wire ncf_pterms1 =
		  ~nmispredicted & ~nq_state[0]
		& enbl_br_fold
		& ~ntaken_cti_in_e
		;

	wire cf_pterms1;
	Mflipflop_1 cf_pterms1_reg_1(cf_pterms1,ncf_pterms1,ss_clock,hold) ;

	wire ncf_pterms2 =
		  ~(ncant_unload & ~can_fold)
		& ~trap_cyc1 & ~reset
		;

	wire cf_pterms2;
	Mflipflop_1 cf_pterms2_reg_1(cf_pterms2,ncf_pterms2,ss_clock,hold) ;

	// added last minterm because of a bug found in the
	// system.  a folded branch followed an instruction that
	// was interlocked.  the branch/del-slot were stripped
	// from the queue and put into the oops register.
	// the state of the machine is configured to use the
	// oops registers as the next instructions, but because
	// the fall thru instruction has a bad inst fetch trap
	// associated with it, the sequential_f turned off, which
	// turns off can_fold_am.  thus, the branch in the oops
	// register that was folded disappears and if the branch
	// is to be taken, it looks like the branch never occured
	// and the fall thru path is executed.  this last minterm
	// fixes this bug by making sure that if a branch got folded
	// into the oops register, it will still be folded from the
	// oops register.
	wire can_fold_am =
		  cf_pterms1 & cf_pterms2
		& br_in_TOQ		// & ~bad_toq
		& ~gen_help_op
		& ~cti_in_d_nvd
//		& ~TRAP
		& ~kill_fetch_fill	// we'll see
		& valid_decode_nilock
//		& ~rett_in_pipe		// same term in cti_in_d_nvd
		& ~wrspec_in_pipe & (
			  ~q_state[1] & ~q_state[2]
			| sequential_f
			)
		| (~reset & last_can_fold & cant_unload
			& ~(trap_cyc1 | trap_cyc2))
		;

	assign can_fold = ~bad_toq & can_fold_am;

/*	wire can_fold =
		  ~reset & ~mispredicted
		& br_in_TOQ & ~q_state[0] & ~bad_toq
		& ~(cant_unload & ~last_can_fold)
		& ~gen_help_op
		& ~(cti_in_d) // | d_help)
	 	& enable_fold & ~taken_cti_in_e & ~TRAP
		& valid_decode_nilock
		& ~trap_cyc2 & ~rett_in_pipe
		& ~wrspec_in_pipe & (
			  ~q_state[1] & ~q_state[2]
			| sequential_f	// | looks_seq
			)
//		& valid_decode
		;
*/
	wire sel_old_aa = cant_unload & last_can_fold;

	Mflipflop_1 last_cf_reg_1(last_can_fold,can_fold,ss_clock,hold) ;

/*
 * branch pipeline
 */
// hold_br must be on with interlock and ~iu_fetch_f
//	wire hold_br1 = ~reset & (
//		   ilock
//		| ~iu_fetch_f & ~gen_help
//		)
//		| hold
//		;
	// see nmult_fold_d for changes to hold_br1
	wire hold_br1 = ~reset & ~fold_in_e & (
		   ilock
		| gen_help_op & ~fold_in_d & valid_decode_nilock
		)
		| ~reset & ~fold_in_d & ilock	// see note
		| hold
		;
	// note - this term keeps fold_in_d from turning on
	// if can_fold is on, but interlock is on, too.
	// can_fold uses valid_decode_nilock, instead of
	// valid_decode.

	wire [3:0] toq_cond = new_toq_entry_bits[28:25];
	wire [3:0] dbr_cond;
	Mflipflop_4 dbr_cond_reg_4(dbr_cond,toq_cond,ss_clock,hold_br1) ;

	wire toq_annul = new_toq_entry_bits[29];
	wire dbr_annul;
	Mflipflop_1 dbr_annul_reg_1(dbr_annul,toq_annul,ss_clock,hold_br1) ;

	Mflipflop_1 f_in_d_reg_1(fold_in_d,can_fold,ss_clock,hold_br1) ;

//	wire hold_br2 = ~reset & (ilock | hold);
//	wire hold_br2 = hold;

/*
 * not needed anymore - keep in case i need to bring em back
	REGWIRE [3:0] ebr_cond;
	REG(ebr_cond_reg,4,ebr_cond,dbr_cond,ss_clock,hold)

	REGWIRE ebr_annul;
	REG(ebr_annul_reg,1,ebr_annul,dbr_annul,ss_clock,hold)
 */

	wire nfold_in_e = fold_in_d & ~ilock & ~IU_in_trap;

	Mflipflop_1 f_in_e_reg_1(fold_in_e,nfold_in_e,ss_clock,hold) ;

	
/*
 * branch prediction stuff
 */

//	wire prediction = 1'b1;
//	wire predict_taken = prediction & fold_in_d;

	wire predict_taken = fold_in_d;		// always predict taken

/*
 * try speedup by doing fold_taken, mispredicted and fold_annul
 * determination in D of folded br instead of E.
	REG(lptaken_reg,1,last_predict_taken,predict_taken,ss_clock,hold)

	wire fold_taken;
	Miccev_fold iccev_fold (fold_taken, ebr_cond, ccm);

	wire mispredicted = fold_in_e & (fold_taken ^ last_predict_taken);
 */

/*
 * don't need to pipeline this - we'll see
	REGWIRE fold_taken;
	REG(fold_taken_reg,1,fold_taken,nfold_taken,ss_clock,hold_br1)
 */

	assign nmispredicted =
		  fold_in_d
		& ~IU_in_trap
		& (nfold_taken ^ predict_taken);

	Mflipflop_1 misp_reg_1(mispredicted,nmispredicted,ss_clock,hold_br1) ;


	wire nmult_fold_d = ~reset & (	// based on hold_br1
		  ilock
	        | gen_help & ~fold_in_d
		)
		;

	wire lta_hold = ~reset & (
		    ilock
		  | gen_help & ~fold_in_d
		)
		;

	// used to detect if a folded bicc is held up in D (typically
	// due to the inst in D is interlocked).
	wire multiple_fold_d;
	Mflipflop_1 mult_fold_d_reg_1(multiple_fold_d,nmult_fold_d,ss_clock,hold) ;

	wire first_fold_d_predict =
		predict_taken & ~multiple_fold_d;

/*
 * Check annul for folded branch - annul E into W
 */
/*
 * try faster fold annul by doing it in D, not in E
	wire e_condbr_always = ebr_cond==BR_ALWAYS;
	wire fold_ba_annul = e_condbr_always & fold_in_e & ebr_annul;
	wire fold_bicc_annul = fold_in_e & ebr_annul & ebr_annul & ~fold_taken;
	wire fold_annul = fold_ba_annul | fold_bicc_annul;
 */

	wire d_condbr_always = dbr_cond==`BR_ALWAYS;
	wire nfold_ba_annul = d_condbr_always & fold_in_d & dbr_annul;
	wire nfold_bicc_annul = fold_in_d & dbr_annul & ~nfold_taken;

// 9-19-96  duplicate nfold_annul signal to ease the loading problem here
	wire nfold_annul = ~reset & ~IU_in_trap &
		 (nfold_ba_annul | nfold_bicc_annul);
	wire nfold_annul_1 = ~reset & ~IU_in_trap &
		 (nfold_ba_annul | nfold_bicc_annul);
	wire nfold_annul_2 = ~reset & ~IU_in_trap &
		 (nfold_ba_annul | nfold_bicc_annul);
	wire nfold_annul_3 = ~reset & ~IU_in_trap &
		 (nfold_ba_annul | nfold_bicc_annul);

// 9-19-96: duplicate fold_annul flops to individually feed each decode subblock
	Mflipflop_1 fold_annul_reg_1( fold_annul,  nfold_annul, ss_clock, hold );
	Mflipflop_1 fold_annul_reg_2( fold_annul2, nfold_annul_1, ss_clock, hold );
	Mflipflop_1 fold_annul_reg_3( fold_annul3, nfold_annul_1, ss_clock, hold );
	Mflipflop_1 fold_annul_reg_4( fold_annul4, nfold_annul_2, ss_clock, hold );
	Mflipflop_1 fold_annul_reg_5( fold_annul5, nfold_annul_2, ss_clock, hold );
	Mflipflop_1 fold_annul_reg_6( fold_annul6, nfold_annul_3, ss_clock, hold );
	Mflipflop_1 fold_annul_reg_7( fold_annul7, nfold_annul_3, ss_clock, hold );

//	REG(fold_annul_reg,1,fold_annul,nfold_annul,ss_clock,hold_br1)

/********************* FPC SELECTS ***********************/

/*
 * generate selects for FPC
 */
// note there is something wrong with fcc_taken - it turns on
// when there is a sethi in D or bicc in D.

	assign nlast_taken = ~nfold_annul & (
		  fcc_taken & fbr_in_d_vd
		| bicc_taken & br_in_d_vd
		);

	Mflipflop_1 last_taken_reg_1(last_taken,nlast_taken,ss_clock,hold) ;

/*
	REGWIRE last_fbtaken;
	REG(last_fbtaken_reg,1,last_fbtaken,fcc_taken,ss_clock,hold)

	REGWIRE last_brtaken;
	REG(last_brtaken_reg,1,last_brtaken,bicc_taken,ss_clock,hold)

	assign last_taken = ~fold_annul & (
		  last_fbtaken & fbr_in_e
		| last_brtaken & br_in_e
		);
 */

// sel_post_reset - this is to hold the FPC for the first fetch
// since DPC is already 0 after the reset.  without this select,
// the 1st DPC would be 4.  hld_dpc may be a long path, so rethink
// how to do this.

	wire nsel_post_reset = reset & del_resetm;
	Mflipflop_1 sel_pr_reg_1(sel_post_reset,nsel_post_reset,ss_clock,hold) ;

	wire last_null_fetch;
	Mflipflop_1 last_null_fetch_reg_1(last_null_fetch,~iu_fetch_f,ss_clock,hold) ;

/*
 * cant_unload is too slow, even with all registered operands
	REGWIRE p_reset1;
	REG(p_reset1_reg,1,p_reset1,reset,ss_clock,hold)

	REGWIRE p_untaken_empty_ilock;
	REG(p_uteil_reg,1,p_untaken_empty_ilock,untaken_empty_ilock,
		ss_clock,hold)

	assign cant_unload = last_null_fetch & ~p_reset1 & ~ANNUL
				& ~p_untaken_empty_ilock & ~fetch_alt;
 */

	assign ncant_unload =
		  ~iu_fetch_f & ~reset
		& ~nANNUL & ~untaken_empty_ilock
		& ~(fld_hlp_misp | nmispredicted)
		;

	Mflipflop_1 cant_unload_reg_1(cant_unload,ncant_unload,ss_clock,hold) ;


	assign hld_dir2 = cant_unload;
//		  hold | cant_unload
//		| (~untaken_empty_ilock & p_untaken_empty_ilock)
//		;

	// ~last_can_fold & can_fold - used to disable sel_p_fpc if prev cycle
	// no fetch was done and can_fold was off (because queue empty) *and*
	// an inst was loaded to Q which fulfills can_fold criteria in
	// *next* cycle.  need to put out sel_i2dpc_fpc instead of sel_p_fpc,

	wire nselpfpc_t1 =
		  ~iu_fetch_f & ~njmp_rett_in_w
		& ~trap_cyc1;

	wire nselpfpc_t2 =
		  ~(nmispredicted & gen_help)
		& ~(nfold_annul & ~gen_help)
		;

	wire selpfpc_t1, selpfpc_t2;
	Mflipflop_1 selpfpc_t1_reg_1(selpfpc_t1,nselpfpc_t1,ss_clock,hold) ;
	Mflipflop_1 selpfpc_t2_reg_1(selpfpc_t2,nselpfpc_t2,ss_clock,hold) ;

	wire sel_p_fpc =
		  selpfpc_t1 & selpfpc_t2 & ~sel_post_reset
		& ~(~last_can_fold & can_fold)
		& ~fold_in_d
		;

	// this version assumes can_fold = 1
	wire sel_p_fpc_cf1 =
		  selpfpc_t1 & selpfpc_t2 & ~sel_post_reset
		& last_can_fold
		& ~fold_in_d
		;

	// this version assumes can_fold = 0
	wire sel_p_fpc_cf0 =
		  selpfpc_t1 & selpfpc_t2 & ~sel_post_reset
		& ~fold_in_d
		;
	/*
	 * try to do this faster
	wire sel_p_fpc = last_null_fetch & ~sel_post_reset & ~jmp_rett_in_w
		& ~trap_cyc2 & ~(mispredicted & d_help)
		& ~(~last_can_fold & can_fold)
		& ~fold_in_d
		& ~(fold_annul & ~d_help)
		;
	 */

	wire nltafpc_t1 =
		  njmp_rett_in_w
		| (call_in_d_vd & ~nfold_annul)
		;

	wire nltafpc_t2 =
		  trap_cyc1 & ~ER_SDOUT
		| (br_fbr_in_d & nlast_taken)
		;

	wire ltafpc_t1, ltafpc_t2;
	Mflipflop_1 ltafpc_t1_reg_1(ltafpc_t1,nltafpc_t1,ss_clock,hold) ;
	Mflipflop_1 ltafpc_t2_reg_1(ltafpc_t2,nltafpc_t2,ss_clock,hold) ;

	wire sel_lta_fpc = ~sel_post_reset &
		(ltafpc_t1 | ltafpc_t2 | predict_taken)
		;

	/*
	 * try to do this faster
	wire sel_lta_fpc = ~sel_post_reset &
		 ((br_fbr_in_e & last_taken)
			| call_in_e & ~fold_annul
			| jmp_rett_in_w
			| trap_cyc2 | predict_taken);
	*/

	wire sel_alt_tag = mispredicted &
		~(last_null_fetch & ~fold_annul2 & ~d_help);

	wire sel_i1pfpc_fpc =
		  ~last_can_fold & can_fold
		& last_null_fetch & ~sel_p_fpc;

	// this version assumes can_fold = 1. there is no
	// mirror that assumes can_fold = 0 since it will
	// always be 0.
	wire sel_i1pfpc_fpc_cf1 =
		  ~last_can_fold
		& last_null_fetch & ~sel_p_fpc_cf1;


	wire sel_i2dpc_fpc = can_fold & ~sel_p_fpc & ~sel_i1pfpc_fpc;

	// this version assumes can_fold = 1.  again, no
	// version with cf=0 is required
	wire sel_i2dpc_fpc_cf1 = ~sel_p_fpc_cf1 & ~sel_i1pfpc_fpc_cf1;

	wire sel_idpc_fpc = ~sel_lta_fpc & ~sel_post_reset
		& ~sel_p_fpc & ~sel_alt_tag & ~sel_i2dpc_fpc
		& ~sel_i1pfpc_fpc;

	// this version assumes can_fold = 1
	wire sel_idpc_fpc_cf1 = ~sel_lta_fpc & ~sel_post_reset
		& ~sel_p_fpc_cf1 & ~sel_alt_tag & ~sel_i2dpc_fpc_cf1
		& ~sel_i1pfpc_fpc_cf1;

	// this version assumes can_fold = 0
	wire sel_idpc_fpc_cf0 = ~sel_lta_fpc & ~sel_post_reset
		& ~sel_p_fpc_cf0 & ~sel_alt_tag
		;

	// faster way of determining if the low bit of FPC is 1 or 0.
	// if in the DP's, too many boundary crossings.  i'm
	// hoping that this is faster.
	wire lta_hold_real = lta_hold | hold;
	wire lta_low;
	Mflipflop_1 lta_low_reg_1(lta_low,nlta_low,ss_clock,lta_hold_real) ;
	wire dpc_low;
	Mflipflop_1 dpc_low_reg_1(dpc_low,ndpc_low,ss_clock,hold) ;
	wire pfpc_low;
	Mflipflop_1 pfpc_low_reg_1(pfpc_low,fpc_low,ss_clock,hold) ;
Next123
HierarchyFilesModulesSignalsTasksFunctionsHelp

This page: Created:Thu Aug 19 11:59:46 1999
From: ../../../sparc_v8/ssparc/iu/Mdecode/rtl/pc_cntl.v

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