HierarchyFilesModulesSignalsTasksFunctionsHelp
Prev123
	wire alttag_low;
	Mflipflop_1 alttag_low_reg_1(alttag_low,nalttag_low,ss_clock,hold_alt) ;
	wire dpc_low_l = ~dpc_low;
	wire pfpc_low_l = ~pfpc_low;

	// a similar mux is in the PC datapath.
	wire fpc_low_int;
    // Expanded macro begin.
    // cmux7dnm(fpc_low_int_mux, 1, fpc_low_int,  		lta_low,  sel_lta_fpc,  		dpc_low_l,  sel_idpc_fpc,  		1'b0,  sel_post_reset,  		pfpc_low,  sel_p_fpc,  		alttag_low,  sel_alt_tag,  		pfpc_low_l,  sel_i1pfpc_fpc,  		dpc_low,  sel_i2dpc_fpc)
    function [1:1] fpc_low_int_mux ;
        input [1:1] in0_fn ;
        input s0_fn ;
        input [1:1] in1_fn ;
        input s1_fn ;
        input [1:1] in2_fn ;
        input s2_fn ;
        input [1:1] in3_fn ;
        input s3_fn ;
        input [1:1] in4_fn ;
        input s4_fn ;
        input [1:1] in5_fn ;
        input s5_fn ;
        input [1:1] in6_fn ;
        input s6_fn ;
        reg [1:1] out_fn ;
        begin
            case ({ sel_i2dpc_fpc,  sel_i1pfpc_fpc,  sel_alt_tag,  sel_p_fpc,  sel_post_reset,  sel_idpc_fpc,  sel_lta_fpc}) /* synopsys parallel_case */
                7'b0000001:     out_fn = in0_fn ;
                7'b0000010: out_fn = in1_fn ;
                7'b0000100:     out_fn = in2_fn ;
                7'b0001000: out_fn = in3_fn ;
                7'b0010000:     out_fn = in4_fn ;
                7'b0100000: out_fn = in5_fn ;
                7'b1000000:     out_fn = in6_fn ;
                default:        out_fn = 65'hx;
            endcase
            fpc_low_int_mux = out_fn ;
        end
    endfunction
    assign fpc_low_int = fpc_low_int_mux( 		lta_low,  sel_lta_fpc,  		dpc_low_l,  sel_idpc_fpc,  		1'b0,  sel_post_reset,  		pfpc_low,
    sel_p_fpc,  		alttag_low,  sel_alt_tag,  		pfpc_low_l,  sel_i1pfpc_fpc,  		dpc_low,  sel_i2dpc_fpc) ;
    // Expanded macro end.


	// this assumes that can_fold = 1
	wire fpc_low_int_cf1;
    // Expanded macro begin.
    // cmux7dnm(fpc_low_int_cf1_mux, 1, fpc_low_int_cf1,  		lta_low,  sel_lta_fpc,  		dpc_low_l,  sel_idpc_fpc_cf1,  		1'b0,  sel_post_reset,  		pfpc_low,  sel_p_fpc_cf1,  		alttag_low,  sel_alt_tag,  		pfpc_low_l,  sel_i1pfpc_fpc_cf1,  		dpc_low,  sel_i2dpc_fpc_cf1)
    function [1:1] fpc_low_int_cf1_mux ;
        input [1:1] in0_fn ;
        input s0_fn ;
        input [1:1] in1_fn ;
        input s1_fn ;
        input [1:1] in2_fn ;
        input s2_fn ;
        input [1:1] in3_fn ;
        input s3_fn ;
        input [1:1] in4_fn ;
        input s4_fn ;
        input [1:1] in5_fn ;
        input s5_fn ;
        input [1:1] in6_fn ;
        input s6_fn ;
        reg [1:1] out_fn ;
        begin
            case ({ sel_i2dpc_fpc_cf1,  sel_i1pfpc_fpc_cf1,  sel_alt_tag,  sel_p_fpc_cf1,  sel_post_reset,  sel_idpc_fpc_cf1,  sel_lta_fpc}) /* synopsys parallel_case */
                7'b0000001:     out_fn = in0_fn ;
                7'b0000010: out_fn = in1_fn ;
                7'b0000100:     out_fn = in2_fn ;
                7'b0001000: out_fn = in3_fn ;
                7'b0010000:     out_fn = in4_fn ;
                7'b0100000: out_fn = in5_fn ;
                7'b1000000:     out_fn = in6_fn ;
                default:        out_fn = 65'hx;
            endcase
            fpc_low_int_cf1_mux = out_fn ;
        end
    endfunction
    assign fpc_low_int_cf1 = fpc_low_int_cf1_mux( 		lta_low,  sel_lta_fpc,  		dpc_low_l,  sel_idpc_fpc_cf1,  		1'b0,  sel_post_reset,  		pfpc_low,
    sel_p_fpc_cf1,  		alttag_low,  sel_alt_tag,  		pfpc_low_l,  sel_i1pfpc_fpc_cf1,  		dpc_low,  sel_i2dpc_fpc_cf1) ;
    // Expanded macro end.


	// this accumes that can_fold = 0
	wire fpc_low_int_cf0;
    // Expanded macro begin.
    // cmux5dnm(fpc_low_int_cf0_mux, 1, fpc_low_int_cf0,  		lta_low,  sel_lta_fpc,  		dpc_low_l,  sel_idpc_fpc_cf0,  		1'b0,  sel_post_reset,  		pfpc_low,  sel_p_fpc_cf0,  		alttag_low,  sel_alt_tag)
    function [1:1] fpc_low_int_cf0_mux ;
        input [1:1] in0_fn ;
        input s0_fn ;
        input [1:1] in1_fn ;
        input s1_fn ;
        input [1:1] in2_fn ;
        input s2_fn ;
        input [1:1] in3_fn ;
        input s3_fn ;
        input [1:1] in4_fn ;
        input s4_fn ;
        reg [1:1] out_fn ;
        begin
            case ({ sel_alt_tag,  sel_p_fpc_cf0,  sel_post_reset,  sel_idpc_fpc_cf0,  sel_lta_fpc}) /* synopsys parallel_case */
                5'b00001:       out_fn = in0_fn ;
                5'b00010: out_fn = in1_fn ;
                5'b00100:       out_fn = in2_fn ;
                5'b01000: out_fn = in3_fn ;
                5'b10000:       out_fn = in4_fn ;
                default:        out_fn = 65'hx;
            endcase
            fpc_low_int_cf0_mux = out_fn ;
        end
    endfunction
    assign fpc_low_int_cf0 = fpc_low_int_cf0_mux( 		lta_low,  sel_lta_fpc,  		dpc_low_l,  sel_idpc_fpc_cf0,  		1'b0,  sel_post_reset,  		pfpc_low,  sel_p_fpc_cf0,  		alttag_low,  sel_alt_tag) ;
    // Expanded macro end.



/************************* BR INTERLOCK ****************************/

/*
 * figure out if we have to interlock - this case involves an
 * untaken branch in E and an empty queue
 * 
 * also a save/restore in the delay slot of an annuled and folded
 * branch.
 */
	wire sv_rest_in_d =
		  valid_decode
		& (d_hop3==`SAVE | d_hop3==`RESTORE);

	wire sv_rest_in_e;
	Mflipflop_1 sv_rest_in_e_reg_1(sv_rest_in_e,sv_rest_in_d,ss_clock,hold) ;

	wire nuntaken_emt_il =
		  br_fbr_in_d & ~nlast_taken
		| call_in_d_vd & nfold_annul
		| nkill_jmp_ld
		;

	wire untaken_emt_il;
	Mflipflop_1 untaken_emt_il_reg_1(untaken_emt_il,nuntaken_emt_il,ss_clock,hold) ;

	assign untaken_empty_ilock =
		  q_state[0] & untaken_emt_il;

//		& (
//		   br_fbr_in_e & ~last_taken
//		 | call_in_e & fold_annul
//		 | kill_jmp_ld
//		  )
//		;

	wire sv_rest_fold_ilock =
		(sv_rest_in_e & fold_annul2 & ~mispredicted)
		;

	assign sv_rest_recirc =
		sv_rest_in_e & fold_annul2 & ~TRAP;

/************************ IFLUSH junk ********************************/

	wire flush_ic_e = ~fold_annul & (
		  flush_asi_e & e_hop3==`STA
		| e_hop3==`IFLUSH)
		;

	wire nkill_fetch_fill =
		  ~nq_state[0] & flush_ic_e & ~can_fold;

//	wire kffr_hold = ~kill_fetch_fill & hold;
	Mflipflop_1 kill_fetch_fill_reg_1(kill_fetch_fill,nkill_fetch_fill, 		ss_clock,hold) ;

	// this term turns on if there is a flush_ic_e and
	// an attempt by the I$ or MMU to force the ifill address.
	// it is also found in the module Mhold_control to hold
	// the pipe if this condition is detected.  this logic was
	// in the I$ control, but timing problems require it in
	// Mdecode and Mhold_control.
	wire flsh_fill_conf = force_ifill & flush_ic_e;


/************************ BR FOLD TRAP LOGIC *************************/

/*
 * first case - delay slot of bicc traps and the branch was mispredicted.
 * must send wpc to Mexec instead of tpc since tpc has the pc of the
 * mispredicted inst.
 */

	wire last_misp;
	Mflipflop_1 last_misp_reg_1(last_misp,mispredicted,ss_clock,hold) ;

	wire nfwd_wpc_almost = ~reset & ~trap_cyc2 & (
		  last_misp & TRAP
		| fwd_wpc_almost)
		;

   // this reg turns on when TRAP detected and stays on until trap_cyc2
	Mflipflop_1 fwdwpda_reg_1(fwd_wpc_almost,nfwd_wpc_almost,ss_clock,hold) ;

	wire fwd_wpc = fwd_wpc_almost & trap_cyc2;


/*
 * second case - inst before a folded pair takes a trap.  need to
 * fwd tpc-4 not tpc.
 */

	wire ntrap_bf_fold = ~reset & ~trap_cyc2 & (
		  TRAP & (fold_in_e | multiple_fold_d & fold_in_d)
		| trap_before_fold)
		;

   // this reg turns on when TRAP detected and stays on until trap_cyc2
	Mflipflop_1 trap_bf_fold_reg_1(trap_before_fold,ntrap_bf_fold,ss_clock,hold) ;

	
	wire fwd_tpcm4 = trap_before_fold & trap_cyc2;
	wire use_tpc = ~fwd_wpc & ~fwd_tpcm4;

/************************* FETCH SELECTION ***************************/

/*
 * determine fetch source
 */
	wire nfchic_t0 =
		  ~ncant_unload & ~(nmispredicted | fld_hlp_misp);
	wire nfchic_t1 =
		  nlast_taken & br_fbr_in_d
		| nq_state[0]
		;
	wire nfchic_t2 =
		  call_in_d_vd & ~nfold_annul
		| trap_cyc1
		| njmp_rett_in_w
		;

	wire fchic_t0,fchic_t1,fchic_t2;
	Mflipflop_1 fchic_t0_reg_1(fchic_t0,nfchic_t0,ss_clock,hold) ;
	Mflipflop_1 fchic_t1_reg_1(fchic_t1,nfchic_t1,ss_clock,hold) ;
	Mflipflop_1 fchic_t2_reg_1(fchic_t2,nfchic_t2,ss_clock,hold) ;

	wire fetch_ic = fchic_t0 & (
		  fchic_t1 | fchic_t2
		| predict_taken & ~multiple_fold_d
		| can_fold & q_state[1]
		)
		;

	// this assumes can_fold = 1
	wire fetch_ic_cf1 = fchic_t0 & (
		  fchic_t1 | fchic_t2
		| predict_taken & ~multiple_fold_d
		| q_state[1]
		)
		;

	// this assumes can_fold = 0
	wire fetch_ic_cf0 = fchic_t0 & (
		  fchic_t1 | fchic_t2
		| predict_taken & ~multiple_fold_d
		)
		;

	// use this version in stop_fetch.  don't need the
	// can_fold term in here.  here's the reasoning:
	//	fetch_ic would turn on we can fold a branch and the
	//	Q has one entry.  this should cause stop_fetch
	//	to not be asserted.  however can_fold will NOT turn on
	//	if the TOQ has an iacc exc associated with it, so
	//	the can_fold & q_state[1] term would not have turned
	//	on anyway.  if the TOQ is a Bicc without iacc exc
	//	status, but the delay slot in the Q has exc status,
	//	the can_fold & q_state[1] term will also not turn on
	//	since there is more than one entry in the Q.

	wire fetch_ic_trunc = fchic_t0 & (
		  fchic_t1 | fchic_t2
		| predict_taken & ~multiple_fold_d
		)
		;

	/*
	 * try to do this faster
	wire fetch_ic = ~cant_unload & ~(mispredicted | keep_alt) & (
		  last_taken & br_fbr_in_e
		| call_in_e & ~fold_annul
		| q_state[0]
		| trap_cyc2
		| jmp_rett_in_w
		| predict_taken & ~multiple_fold_d
		| can_fold & q_state[1]
		)
		;
	 */
	wire toq_2_alt = predict_taken & ~multiple_fold_d;

	assign hold_alt = ~toq_2_alt;	// ~iu_fetch_f & ~toq_2_alt

	wire use_f_nold = fetch_ic & fpc_low_int;	// & iu_fetch_f

	// this version assumes can_fold = 1
	wire fetch_ic_even_cf1 =
		fetch_ic_cf1 & ~fpc_low_int_cf1 & ~cant_unload;

	// this version assumes can_fold = 0
	wire fetch_ic_even_cf0 =
		fetch_ic_cf0 & ~fpc_low_int_cf0 & ~cant_unload;

	wire fetch_ic_even;
    // Expanded macro begin.
    // cmux2(fetch_ic_even_mux, 1, fetch_ic_even,  		fetch_ic_even_cf0, fetch_ic_even_cf1, can_fold)
    function [1:1] fetch_ic_even_mux ;
        input [1:1] in0_fn ;
        input [1:1] in1_fn ;
        input select_fn ;
        reg [1: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
            fetch_ic_even_mux = out_fn ;
        end
    endfunction
    assign fetch_ic_even = fetch_ic_even_mux( 		fetch_ic_even_cf0, fetch_ic_even_cf1, can_fold) ;
    // Expanded macro end.


/*	wire fetch_ic_even = fetch_ic & ~fpc_low_int & ~cant_unload;*/

	// this version assumes can_fold = 1
	wire fetch_ic_odd_cf1 =
		fetch_ic_cf1 & fpc_low_int_cf1 & ~cant_unload;

	// this version assumes can_fold = 0
	wire fetch_ic_odd_cf0 =
		fetch_ic_cf0 & fpc_low_int_cf0 & ~cant_unload;

	wire fetch_ic_odd;
    // Expanded macro begin.
    // cmux2(fetch_ic_odd_mux, 1, fetch_ic_odd,  		fetch_ic_odd_cf0, fetch_ic_odd_cf1, can_fold)
    function [1:1] fetch_ic_odd_mux ;
        input [1:1] in0_fn ;
        input [1:1] in1_fn ;
        input select_fn ;
        reg [1: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
            fetch_ic_odd_mux = out_fn ;
        end
    endfunction
    assign fetch_ic_odd = fetch_ic_odd_mux( 		fetch_ic_odd_cf0, fetch_ic_odd_cf1, can_fold) ;
    // Expanded macro end.


/*	wire fetch_ic_odd = fetch_ic & fpc_low_int & ~cant_unload; */

	// this reg is just for the performance counter that
	// counts if the IU has done a fetch.  see did_fetch for
	// more details

	wire pfetch_ic_odd;
	Mflipflop_1 pfetch_ic_odd_reg_1(pfetch_ic_odd,fetch_ic_odd,ss_clock,1'b0) ;

//  this wire is so we can tell if we have a mispredicted branch
//  folded with a long multicycle inst - inst in E, help in D,
//  and that help is generating another help.
//  note that gen_help already incorporates fold_annul via valid_decode

	assign fld_hlp_misp = ~reset & (
		  mispredicted & gen_help
		| keep_alt & gen_help
		);

	Mflipflop_1 keep_alt_reg_1(keep_alt,fld_hlp_misp,ss_clock,hold) ;

	assign fetch_alt = (mispredicted | keep_alt);

	wire fetch_SIQ = can_fold & ~q_state[1] & ~cant_unload;

	// this version assumes can_fold = 1
	wire fetch_SIQ_cf1 = ~q_state[1] & ~cant_unload;

	wire fetch_TOQ = ~fetch_ic & ~fetch_alt & ~fetch_SIQ & ~cant_unload;

	// this version assumes can_fold = 1
	wire fetch_TOQ_cf1 =
		~fetch_ic_cf1 & ~fetch_alt & ~fetch_SIQ_cf1 & ~cant_unload;
	// this version assumes can_fold = 0
	wire fetch_TOQ_cf0 = ~fetch_ic_cf0 & ~fetch_alt & ~cant_unload;

//	REGWIRE last_fetch_TOQ;
//	REG(lfT_reg,1,last_fetch_TOQ,fetch_TOQ,ss_clock,hold)



/************************** QUEUE CONTROL ************************/
/*
 * determine if can't load $ data into Q
 */

	assign nkill_jmp_ld = e_hop3==`JMP & fold_annul;
	Mflipflop_1 kill_jmp_ld_reg_1(kill_jmp_ld,nkill_jmp_ld,ss_clock,hold) ;

	// this term is used in the event that a bicc/bfcc/call is
	// in D and got interlocked. the logic allows the target
	// address to go out, but we cannot load that data into
	// the queue in the next cycle.  reason: because the target
	// address will stay on the iva for as long as the interlock
	// exists + 1 cycle for the cti to be in D uninterlocked.
	// this would cause the target to be fetched multiple times
	// and be loaded into the queue.
	wire nkill_ilock_br_fetch =
		  valid_decode_nilock & ilock
		& (d_hop2==`BICC | d_hop2==`BFCC | d_hop==`CALL);

	wire kill_ilock_br_fetch;
	Mflipflop_1 kill_ilock_br_fetch_reg_1(kill_ilock_br_fetch, 		nkill_ilock_br_fetch,ss_clock,hold) ;

	// the wo/wu terms were added to fix a possible problem
	// if software does not mark configuration registers
	// as unexecutable.  if a restore/save is followed by
	// a jmp, and that restore/save traps from a wo/wu,
	// the jmp may read a bad value from the RF.  if that 
	// address points to a configuration register and software
	// mistakenly didn't mark that page not-execute, the
	// machine will hang since the MMU and I$ do not know
	// that that device will not return an instruction,
	// and so will never release the pipeline.
	// the proper fix is in software.
	// we have decided to not put this patch in the IU,
	// so it is commented out here.

	wire wo_wu_trap_w = (wo_trap_w | wu_trap_w) & TRAP;

	wire wo_wu_trap_r;
	Mflipflop_1 wo_wu_trap_r_reg_1(wo_wu_trap_r,wo_wu_trap_w,ss_clock,hold) ;

	// this term is in there to keep the IU from fetching instructions
	// if there is an instruction marked with an invalid access
	// error or protection violation in the queue.  only need to
	// look at entries 1-3 since these fetches always occur on
	// the double word.  if qx_iae and qx_ptc are both 1, that
	// indicates a watchpoint trap.  do not stop fetching because
	// of watchpoint traps, so use XOR, not OR.

	wire stop_fetch = ~trap_cyc1 & ~trap_cyc2 & ~fetch_ic_trunc & (
		  (q_state[3] | q_state[4]) & (q3_iae ^ q3_ptc)
		| q_state[2] & (q2_iae ^ q2_ptc)
		| q_state[1] & (q1_iae ^ q1_ptc)
		)
		| wo_wu_trap_r
		;

	wire cant_load_part1 =
		  br_fbr_in_e & ~last_taken
		| call_in_e & fold_annul
		| mispredicted | keep_alt
		| kill_jmp_ld
		| kill_ilock_br_fetch
		| last_force_dva
		| kill_fetch_fill
		;

	// this version has long path thru fpc_low_int
	wire cant_load =
		  fetch_ic & fpc_low_int
		| cant_load_part1
		| stop_fetch
		;

	// this assumes can_fold = 1
	wire cant_load_cf1 =
		  fetch_ic_cf1 & fpc_low_int_cf1
		| cant_load_part1
		| stop_fetch
		;

	// this assumes can_fold = 0
	wire cant_load_cf0 =
		  fetch_ic_cf0 & fpc_low_int_cf0
		| cant_load_part1
		| stop_fetch
		;


		//| call_in_e
		// need to add ic2alt term- what is call_in_e here for?
		// i dunno - it shouldn't be
//		| hold_br1 & fold_in_d

	wire nflshq_t1 =
		  br_fbr_in_d & nlast_taken
		| njmp_rett_in_w
		| fld_hlp_misp
		;
	wire nflshq_t2 =
		  call_in_d_vd & ~nfold_annul
		| nmispredicted
		;

	wire flshq_t1, flshq_t2;
	Mflipflop_1 flshq_t1_reg_1(flshq_t1,nflshq_t1,ss_clock,hold) ;
	Mflipflop_1 flshq_t2_reg_1(flshq_t2,nflshq_t2,ss_clock,hold) ;

	assign flushq =
		  flshq_t1 | flshq_t2
//		| IU_in_trap
		| trap_cyc1 | trap_cyc2
		| first_fold_d_predict
		;
	/*
	 * do this faster
	wire flushq =
		  br_fbr_in_e & last_taken
		| call_in_e & ~fold_annul
		| jmp_rett_in_w
		| IU_in_trap
		| first_fold_d_predict
		| mispredicted | keep_alt
		;
	 */
/*
 * queue state machine
 */

	wire nqs0 = reset |
		  q_state[0] & cant_load	// | ~iu_fetch_f)
		| q_state[1] & cant_load & fetch_TOQ
		| q_state[2] & cant_load & fetch_SIQ
		| flushq & (fetch_ic & fpc_low_int | cant_load)
		;

	wire nqs1 = ~reset & (
		  q_state[0] & fetch_ic & ~fpc_low_int & ~cant_load
		| q_state[0] & ~cant_unload & ~cant_load & ~flushq & fpc_low_int
		| q_state[1] & cant_unload & cant_load & ~flushq
		| q_state[1] & can_fold & ~cant_load
		| q_state[2] & fetch_TOQ & cant_load
		| q_state[3] & fetch_SIQ & cant_load
		| flushq & fetch_ic & ~fpc_low_int   & ~cant_load
		| flushq & cant_unload & fpc_low_int & ~cant_load
		)
		;

	wire nqs2 = ~reset & (
		  q_state[0] & cant_unload & ~cant_load & ~flushq //&~fpc_low
		| q_state[1] & fetch_TOQ & ~cant_load
		| q_state[2] & cant_unload & cant_load & ~flushq
		| q_state[2] & fetch_SIQ & ~cant_load
		| q_state[3] & fetch_TOQ & cant_load
		| q_state[4] & fetch_SIQ & cant_load
		| flushq & cant_unload & ~fpc_low_int & ~cant_load
		)
		;

	wire nqs3 = ~reset & (
		  q_state[1] & cant_unload & ~cant_load & ~flushq
		| q_state[2] & fetch_TOQ & ~cant_load
		| q_state[3] & cant_unload & ~flushq
		| q_state[3] & fetch_SIQ & ~cant_load
		| q_state[4] & fetch_TOQ
		)
		;

	wire nqs4 = ~reset & (
		  q_state[2] & cant_unload & ~cant_load & ~flushq
		| q_state[3] & fetch_TOQ & ~cant_load
		| q_state[4] & cant_unload & ~flushq
		| q_state[4] & fetch_SIQ & ~cant_load
		)
		;

	assign nq_state = {nqs4,nqs3,nqs2,nqs1,nqs0};
	Mflipflop_5 q_state_reg_5(q_state,nq_state,ss_clock,hold) ;

//	REGWIRE [4:0] last_q_state;
//	REG(lq_state_reg,5,last_q_state,q_state,ss_clock,hold)

/*
 * old style - too slow and complicated
	wire load_q =
		  (nq_state > q_state)
		| (nq_state == q_state) & (fetch_TOQ | fetch_SIQ)
		| flushq & ~nq_state[0]
		;
 */
	wire load_q = ~cant_load & (
		  part_stuff_q
		| fetch_ic & ~fpc_low_int & (q_state[0] | flushq)
		);

	// this register is for performance counter only.  it
	// is used in conjuction with pfetch_ic_odd tp indicate
	// the IU accepted instruction(s) last cycle.  this
	// register is different from llastc_reg since it
	// is free running
	wire pload_q;
	Mflipflop_1 pload_q_reg_1(pload_q,load_q,ss_clock,1'b0) ;

	// special performance counter.  this one indicates that
	// the IU accepted instructions last cycle.

	wire did_fetch = pload_q | pfetch_ic_odd;

	// loaded last cyc is used to indicate is something was
	// loaded into the queue on the last rising edge of clock.
	// it is held by hld_llc.  hld_mar_car hold turns on in the
	// event we get a bicc/bfcc/call in D that gets interlocked.
	// hld_llc turns on one cycle later and stays one cycle longer.
	// in that event, we want to preserve the loaded_lastcyc
	// from from the previous fetch.  load_q will be off as
	// long as the interlocked bicc/bfcc/call is in D due
	// to kill_ilock_br_fetch
	wire loaded_lastcyc;
	Mflipflop_1 llastc_reg_1(loaded_lastcyc,load_q,ss_clock,hld_llc) ;

/*
 * Q1 control
 */

	// this version assumes that can_fold = 1
	wire sel_even1_cf1 = ~cant_load_cf1 & (
		  q_state[0] & cant_unload & ~flushq
		| q_state[1] & fetch_TOQ_cf1
		| flushq & cant_unload & ~fpc_low_int_cf1
		| q_state[2] & fetch_SIQ_cf1
		);


	// this version assumes that can_fold = 0
	wire sel_even1_cf0 = ~cant_load_cf0 & (
		  q_state[0] & cant_unload & ~flushq
		| q_state[1] & fetch_TOQ_cf0
		| flushq & cant_unload & ~fpc_low_int_cf0
		);

	wire sel_even1;
    // Expanded macro begin.
    // cmux2(sel_even1_mux, 1, sel_even1,  		sel_even1_cf0, sel_even1_cf1, can_fold)
    function [1:1] sel_even1_mux ;
        input [1:1] in0_fn ;
        input [1:1] in1_fn ;
        input select_fn ;
        reg [1: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
            sel_even1_mux = out_fn ;
        end
    endfunction
    assign sel_even1 = sel_even1_mux( 		sel_even1_cf0, sel_even1_cf1, can_fold) ;
    // Expanded macro end.


	// this version assumes that can_fold = 1
	wire sel_odd1_cf1 = ~cant_load_cf1 & (
		  q_state[0] & fetch_ic_cf1 & ~fpc_low_int_cf1
		| q_state[0] & ~cant_unload & ~flushq
			& fpc_low_int_cf1
		| q_state[1]
		| flushq & fetch_ic_cf1 & ~fpc_low_int_cf1
		| flushq & cant_unload & fpc_low_int_cf1
		);

	// this version assumes that can_fold = 0
	wire sel_odd1_cf0 = ~cant_load_cf0 & (
		  q_state[0] & fetch_ic_cf0 & ~fpc_low_int_cf0
		| q_state[0] & ~cant_unload & ~flushq
			& fpc_low_int_cf0
		| flushq & fetch_ic_cf0 & ~fpc_low_int_cf0
		| flushq & cant_unload & fpc_low_int_cf0
		);

	wire sel_odd1;
    // Expanded macro begin.
    // cmux2(sel_odd1_mux, 1, sel_odd1,  		sel_odd1_cf0, sel_odd1_cf1, can_fold)
    function [1:1] sel_odd1_mux ;
        input [1:1] in0_fn ;
        input [1:1] in1_fn ;
        input select_fn ;
        reg [1: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
            sel_odd1_mux = out_fn ;
        end
    endfunction
    assign sel_odd1 = sel_odd1_mux( 		sel_odd1_cf0, sel_odd1_cf1, can_fold) ;
    // Expanded macro end.



/*
 * these are too slow
	wire sel_even1 =
		  q_state[0] & cant_unload & ~cant_load & ~flushq // ~fpc_low
		| q_state[1] & fetch_TOQ & ~cant_load
		| flushq & cant_unload & ~fpc_low_int & ~cant_load
		| q_state[2] & fetch_SIQ & ~cant_load
		;

	wire sel_odd1 =
		  q_state[0] & fetch_ic & ~fpc_low_int   & ~cant_load
		| q_state[0] & ~cant_unload & ~cant_load & ~flushq
			& fpc_low_int
		| q_state[1] & can_fold & ~cant_load
		| flushq & fetch_ic & ~fpc_low_int   & ~cant_load
		| flushq & cant_unload & fpc_low_int & ~cant_load
		;
 */
	wire sel_fold1 = can_fold & ~(q_state[1] | q_state[2]);

	// this version assumes can_fold = 1
	wire sel_shift1_cf1 = ~sel_even1_cf1 & ~sel_odd1_cf1 & ~sel_fold1;

	// this version assumes can_fold = 0
	wire sel_shift1_cf0 = ~sel_even1_cf0 & ~sel_odd1_cf0 & ~sel_fold1;

	wire sel_shift1;
    // Expanded macro begin.
    // cmux2(sel_shift1_mux, 1, sel_shift1,  		sel_shift1_cf0, sel_shift1_cf1, can_fold)
    function [1:1] sel_shift1_mux ;
        input [1:1] in0_fn ;
        input [1:1] in1_fn ;
        input select_fn ;
        reg [1: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
            sel_shift1_mux = out_fn ;
        end
    endfunction
    assign sel_shift1 = sel_shift1_mux( 		sel_shift1_cf0, sel_shift1_cf1, can_fold) ;
    // Expanded macro end.


//	wire sel_shift1 = fetch_TOQ & ~(sel_even1 | sel_odd1);

	wire hold_q1 = cant_unload & ~q_state[0] & ~flushq;

/*
 * Q2 control
 */
	wire sel_even2 =
		  q_state[1] & cant_unload & ~cant_load & ~flushq
		| q_state[2] & fetch_TOQ & ~cant_load
		| q_state[3] & fetch_SIQ & ~cant_load
		;

	wire sel_odd2 = sel_even1;
	/*
	wire sel_odd2 =
		  q_state[0] & cant_unload & ~cant_load & ~flushq // ~fpc_low
		| q_state[1] & fetch_TOQ & ~cant_load
		| flushq & cant_unload & ~fpc_low_int & ~cant_load
		| q_state[2] & fetch_SIQ & ~cant_load
		;
	 */

//	wire sel_fold2 = can_fold & (q_state[3] | q_state[4]);
	wire sel_fold2 = can_fold & q_state[4];
	wire sel_shift2 = ~sel_even2 & ~sel_odd2 & ~sel_fold2;
//	wire sel_shift2 = fetch_TOQ & ~(sel_even2 | sel_odd2);

	wire hold_q2 = cant_unload & ~(q_state[0] | q_state[1]) & ~flushq;
/*
 * Q3 control
 */
	wire sel_even3 =
		  q_state[2] & cant_unload & ~cant_load
		| q_state[3] & fetch_TOQ & ~cant_load
		| q_state[4] & fetch_SIQ & ~cant_load
		;

	wire sel_odd3 =
		  q_state[1] & cant_unload & ~cant_load & ~flushq
		| q_state[2] & fetch_TOQ & ~cant_load
		| q_state[3] & fetch_SIQ & ~cant_load
		;

	wire sel_shift3 = ~sel_even3 & ~sel_odd3;
//	wire sel_shift3 = fetch_TOQ & ~(sel_even3 | sel_odd3);

	wire hold_q3 = cant_unload & (q_state[3] | q_state[4]) & ~flushq;

/*
 * Q4 control
 */
	wire hold_q4 = cant_unload & q_state[4] & ~flushq;

/********************* FETCH HOLD CONTROL *************************/

// these signals are to get around the slow hold (from slow it_hit_f
// and dt_hit_w).  we can't bring hold into the address generation
// or we will not meet the large setup time required on the I$ address
// at the tag and SRAMs.  the idea is to hold the last fetched data
// in a reg in the queue.  then mux these into the queue when the
// hold is released.  hld_backup is used to hold the register.  this
// turns on when fetch data comes back but pipe is held for a non-I$
// related hold.  it stays asserted until the hold goes away.
// take_icdata is on to select the I$ directly.  it turns off
// when the pipe is held by a non-I$ related hold (pipelined by 1).

	wire take_icdata_l;

	wire ntake_icdata_l =
		  hold_noic & ~hold_ic
		| take_icdata_l & hold
		;

	Mflipflop_1 take_icdata_reg_1(take_icdata_l,ntake_icdata_l,ss_clock,1'b0) ;

	wire take_icdata = ~take_icdata_l;

	wire hld_backup_almost;
	wire hld_backup;
	wire got_idata =
		  hold & ~hold_ic
		| hld_backup_almost & hold
//		  ~hold
		;

	Mflipflop_1 hld_backup_almost_reg_1(hld_backup_almost,got_idata,ss_clock,1'b0) ;

	// the gate with hold has been moved to Mqueue for timing reasons
	assign hld_backup =
		  hld_backup_almost;	// & hold

/************************** GEN ADR SELECTION *********************/

// this signal should be on most of the time when we load something
// into the queue.  not all the time (we use a modified cant_load,
// that does not include fetch_ic and fpc_low_int).  this signal is
// meant only to be used with fetch_ic to determine if the fetch
// data to the IU is being used this cycle or not.  this determines
// which address to send to the I$ this cycle for the fetch next cycle.
// we use this signal because it does not depend on fpc_low_int so should
// cause iva generation to be sped up.

	assign part_stuff_q =
		  flushq & cant_unload 
		| q_state[1] & can_fold
		| q_state[2] & cant_unload 
		| cant_unload  & ~flushq & (q_state[0] | q_state[1])
		| fetch_TOQ & (q_state[1] | q_state[2] | q_state[3])
		| fetch_SIQ & (q_state[2] | q_state[3] | q_state[4])
		;

	// assumes can_fold = 1
	wire part_stuff_q_cf1 =
		  flushq & cant_unload 
		| q_state[1]
		| q_state[2] & cant_unload 
		| cant_unload  & ~flushq & (q_state[0] | q_state[1])
		| fetch_TOQ_cf1 & (q_state[1] | q_state[2] | q_state[3])
		| fetch_SIQ_cf1 & (q_state[2] | q_state[3] | q_state[4])
		;

	// assumes can_fold = 0
	wire part_stuff_q_cf0 =
		  flushq & cant_unload 
		| q_state[2] & cant_unload 
		| cant_unload  & ~flushq & (q_state[0] | q_state[1])
		| fetch_TOQ_cf0 & (q_state[1] | q_state[2] | q_state[3])
		;


	wire stuff_q = ~cant_load_part1 & (
		  part_stuff_q
		)
		;

	// assumes can_fold = 1
	wire stuff_q_cf1 = ~cant_load_part1 & (
		  part_stuff_q_cf1
		)
		;

	// assumes can_fold = 0
	wire stuff_q_cf0 = ~cant_load_part1 & (
		  part_stuff_q_cf0
		)
		;

/*
 * gen addr (iu_iva_g) mux selection
 */

	// need the untaken_empty_ilock term because sadr_aa is
	// no longer dependant on interlock.  what would happen
	// is an untaken br in E would turn on untaken_empty_ilock
	// but because a call/br in D, sadr_aa would turn on
	// causing the wrong inst to be fetched

	wire ANNUL_am;
	Mflipflop_1 ANNUL_am_reg2_1(ANNUL_am,nANNUL,ss_clock,hold) ;
	wire ANNUL = ANNUL_am & ~fold_annul;

	wire saa_null =
		  ~reset & ~ANNUL
		& ~d_nop & ~d_trap
		;

	wire d_hop2bfccc = d_hop2==`BFCC;
	wire sadr_aa_callbfcc = saa_null & (
		  d_hop2bfccc & ~fcc_ilock
		| call_in_d_nvd
		);
	wire dhop2bicc = d_hop2==`BICC;
	wire sadr_aa_bicc_almost = saa_null & dhop2bicc;
	wire sadr_aa = ~iacc_exc_mmumiss_d & (
		  sadr_aa_callbfcc
		| sadr_aa_bicc_almost
		);

	wire sadr_fold_aa = ~untaken_empty_ilock & (
			  can_fold & ~mispredicted & ~reset
			| sadr_aa & ~mispredicted
			)
			;

	// this version assumes can_fold = 1
	wire sadr_fold_aa_cf1 = ~untaken_empty_ilock & (
			  ~mispredicted & ~reset
			| sadr_aa & ~mispredicted
			)
			;

	// this version assumes can_fold = 0
	wire sadr_fold_aa_cf0 = ~untaken_empty_ilock & (
			  sadr_aa & ~mispredicted
			)
			;

	wire sel_inc_alttag = mispredicted | keep_alt;

	wire kill_cti_in_e =
			  br_fbr_in_e & ~last_taken
		        | call_in_e & fold_annul
			| kill_jmp_ld
			;

	// assumes can_fold = 1
	wire sel_last_gen_cf1 = ~sadr_fold_aa_cf1 & ~sel_inc_alttag
		& ~(stuff_q_cf1 | fetch_ic_cf1)
		& ~(kill_cti_in_e)
		;

	// assumes can_fold = 0
	wire sel_last_gen_cf0 = ~sadr_fold_aa_cf0 & ~sel_inc_alttag
		& ~(stuff_q_cf0 | fetch_ic_cf0)
		& ~(kill_cti_in_e)
		;

	wire sel_last_gen;
    // Expanded macro begin.
    // cmux2(sel_last_gen_mux, 1, sel_last_gen,  		sel_last_gen_cf0, sel_last_gen_cf1, can_fold)
    function [1:1] sel_last_gen_mux ;
        input [1:1] in0_fn ;
        input [1:1] in1_fn ;
        input select_fn ;
        reg [1: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
            sel_last_gen_mux = out_fn ;
        end
    endfunction
    assign sel_last_gen = sel_last_gen_mux( 		sel_last_gen_cf0, sel_last_gen_cf1, can_fold) ;
    // Expanded macro end.


	/*
	wire sel_last_gen = ~sadr_fold_aa & ~sel_inc_alttag
		& ~(stuff_q | fetch_ic)
		& ~(kill_cti_in_e)
		;
	*/

	// assumes can_fold = 1
	wire sel_ll_gen_cf1 = ~sadr_fold_aa_cf1 & ~sel_inc_alttag
		& ~q_state[0] & ~loaded_lastcyc
Next123
HierarchyFilesModulesSignalsTasksFunctionsHelp

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

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