// 2 (bypass2=Yreg) into src1. this is used during the ovf detect.
// the signal alus1_b2m is used to select the unshifted version.
assign alus1_b2_shift =
dopc_hidiv0_op
& help_ctr[1]==1'b1
& signed_div
;
// This signal is used to hold the W register during the idiv
// overflow detection step.
wire hold_Wreg =
dopc_hidiv0_op & help_ctr[1]==1'b1
| dopc_hidiv1_op & help_ctr==6'b000000
;
// These signals are used as selects in the high 2 bits [33:32]
// on the src1 mux. use the y (on bypass2) or use the high alu
// or use the default.
wire use_hi_y =
~ss_scan_mode &
(dopc_hidiv0_op & help_ctr==6'b000010
| dopc_hidiv1_op & help_ctr==6'b000000)
;
wire use_hi_alu =
dopc_hidiv1_op & help_ctr>6'b0 & ~ss_scan_mode
;
wire use_hi_rs1_default =
~use_hi_y & ~use_hi_alu
;
// These are the same, except they go to src2 hi mux.
// use the reg file, use low bit of src1 (ONE!), or
// use the default
wire use_hi_rs2 =
~ss_scan_mode &
(dopc_hidiv0_op | dopc_hidiv1_op)
;
// also defined after instanciation of Malu_control
wire use_low_rs1
=
dopc_hidiv3_op & ~ss_scan_mode
;
wire use_hi_rs2_default =
~use_hi_rs2 & ~use_low_rs1 & ~ss_scan_mode
& (hidiv_in_d | himul_in_d)
;
wire not_rs2_rs1_default =
~(use_hi_rs2 | use_low_rs1 | use_hi_rs2_default);
// Save the dividend sign and the final sign for the
// correction step
wire hold_dvnd_sgn
=
hold
| ~(dopc_hidiv1_op & help_ctr==6'b000000)
;
wire dvnd_sgn
;
Mflipflop_1 dvnd_sgn_reg_1(dvnd_sgn,new_sgnA,ss_clock,hold_dvnd_sgn) ;
assign nfinal_sgn =
signed_div
& (result31 ^ dsign_bit2)
;
Mflipflop_1 final_sgn_reg_1(final_sgn,nfinal_sgn,ss_clock,hold_dvnd_sgn) ;
wire idiv_shiftin_low = high_2_1 ~^ final_sgn;
// pipeline help_ctr[5] for 1 cycle to get it aligned
// in the pipe corectly for sticky zero evaluation
wire phelp_ctr5
;
Mflipflop_1 phelp_ctr5_reg_1(phelp_ctr5,help_ctr[5],ss_clock,hold) ;
// this is the sticky zero bit. set if remainder is zero and
// next bit of dividend is zero.
// note that the control logic receives the alu_cc_zero inverted.
// must invert to correct
wire alu_cc_zero_act
= ~alu_cc_zero;
wire sticky_zero
;
wire nsticky_zero
=
// synopsys translate_off
((dopc_hidiv1_op | dopc_hidiv2_op)===1'bx) ? 'bx :
// synopsys translate_on
(dopc_hidiv1_op | dopc_hidiv2_op) ?
(sticky_zero | alu_cc_zero_act)
& (~result31 | phelp_ctr5==1'b1)
: 1'b0;
wire hold_stzr
=
hold
| dopc_hidiv3_op
| eopc_hidiv3
;
Mflipflop_1 sticky_zero_reg_1(sticky_zero,nsticky_zero,ss_clock,hold_stzr) ;
// This is the sticky zero add term. use it to force the carry
// bit during the correction step.
assign div_inv_bit = alu_s1m_0 ^ final_sgn;
wire add_bit
=
div_inv_bit & ~alu_s1m_0
| signed_div & ~div_inv_bit & alu_s1m_0
;
assign zr_add_term =
add_bit ^ (dvnd_sgn & sticky_zero)
;
// Use this signal to clear the MSbit of rs1.
wire pass_hi_rs1 =
~(dopc_hidiv0_op & help_ctr[0]==1'b1)
;
// Detect low 31 bits of dividend (rs1) = 0
wire dvd_z
;
Mflipflop_1 dvd_z_reg_1(dvd_z,alu_cc_zero_act,ss_clock,hold) ;
// This is the overflow detect register. Detect ovf based on
// sign bit from the 34 bit add.
// need to pipeline sgnA to get it in the correct cycle
// pipeline sgnB for speed this up
// note - sgnA has been replaced by (result31 & signed_div)
// and sgnB by dsign_bit2. these are direct equivalents
// and it is hoped they are faster
wire psgnA
;
Mflipflop_1 psgnA_reg_1(psgnA,new_sgnA,ss_clock,hold) ;
wire psgnB
;
Mflipflop_1 psgnB_reg_1(psgnB,dsign_bit2,ss_clock,hold) ;
always @ (psgnA or psgnB or high_2_1 or alu_cc_zero_act or dvd_z) begin
case ( ({psgnA,psgnB}) ) /* synopsys parallel_case */
2'b00: ndet_divovf = ~high_2_1;
2'b01: ndet_divovf = ~high_2_1 & ~(alu_cc_zero_act & dvd_z);
2'b10: ndet_divovf = high_2_1;
2'b11: ndet_divovf = high_2_1 | (alu_cc_zero_act & dvd_z);
endcase
end
wire hold_divovf
=
hold
| ~(dopc_hidiv1_op & help_ctr==6'b000000)
;
Mflipflop_1 det_divovf_reg_1(det_divovf,ndet_divovf,ss_clock,hold_divovf) ;
// force the correct value into DP following an overflow.
// note that the unsigned, the result comes from the alu
// normally.
wire nforce_neg
=
signed_div & final_sgn & det_divovf
& dopc_hidiv3_op
;
wire force_neg_almost
;
Mflipflop_1 force_neg_reg_1(force_neg_almost,nforce_neg,ss_clock,hold) ;
wire force_neg = force_neg_almost & ~ss_scan_mode;
wire nforce_pos
=
signed_div & ~final_sgn & det_divovf
& dopc_hidiv3_op
;
wire force_pos_almost
;
Mflipflop_1 force_pos_reg_1(force_pos_almost,nforce_pos,ss_clock,hold) ;
wire force_pos = force_pos_almost & ~ss_scan_mode;
wire nnot_rs_from_alu
= nforce_neg | nforce_pos;
wire not_rs_from_alu
;
Mflipflop_1 not_rs_from_alu_reg_1(not_rs_from_alu,nnot_rs_from_alu, ss_clock,hold) ;
// BARREL SHIFTER CONTROL
wire nshift_sra
= d_hop3==`SRA;
wire arith_shift;
Mflipflop_1 sra_ff_1( arith_shift, nshift_sra, ss_clock, hold) ;
wire nshift_srl
=
d_hop3==`SRL
;
wire nshift_sll
=
d_hop3==`SLL
;
wire nshift_left
=
nshift_sll | d_opcode==`HSTB | d_opcode==`HSTBA
| d_opcode==`HSTH | d_opcode==`HSTHA
;
wire shift_left;
Mflipflop_1 sll_ff_1( shift_left, nshift_left, ss_clock, hold) ;
/*
* not needed since st aligner is in RF now
// Select Shift amount and register it - default is to select store side
wire nsel_shifts = nshift_sra | nshift_srl | nshift_sll;
REGWIRE sel_shifts;
REG(sel_shifts_reg,1,sel_shifts,nsel_shifts,ss_clock,hold)
wire [4:0] shift_cnt;
CMUX2(nshift_cnt_mux,5,shift_cnt, ({shift_st4,shift_st3,3'b0}), alu_s2i_cnt, sel_shifts)
*/
// ALU / SHIFTER MUX CONTROL
// FROM SHIFTER
wire nrs_from_sh
=
d_hop3==`SRA | d_hop3==`SRL | d_hop3==`SLL
;
wire trs_from_sh
;
Mflipflop_1 rsfsh_ff_1( trs_from_sh, nrs_from_sh, ss_clock, hold) ;
// wire rs_from_sh = ~ss_scan_mode & ~rdtpc & trs_from_sh;
wire rs_from_sh = ~ss_scan_mode & ~trap_cyc1 & trs_from_sh;
// FROM ALU
wire nrs_from_alu
=
d_hop3[8:5]==`ALU
| d_hop3[8:2]==`WR
| d_hop3==`TADDCC | d_hop3==`TADDCCTV
| d_hop3==`TSUBCC | d_hop3==`TSUBCCTV
| d_hop3==`MULSCC
| d_hop2==`SETHI
| d_hop3==`SAVE | d_hop3==`RESTORE
| d_hop3==`TICC
| d_hop==`MEMALL
| (d_hop3[8:5]==`HMEM | d_hop3[8:4]==`HMEMA)
| d_hop3==`JMP | d_hop3==`RETT
| d_hop3==`IFLUSH | e_hop3==`IFLUSH
| dhop3_imulbasic_op
| himul_in_d
| hidiv_in_d
;
wire trs_from_alu
;
Mflipflop_1 rsfalu_ff_1( trs_from_alu, nrs_from_alu, ss_clock, hold) ;
// wire rs_from_alu = ~ss_scan_mode & ~rdtpc & trs_from_alu
// & ~not_rs_from_alu;
wire rs_from_alu = ~ss_scan_mode & ~trap_cyc1 & trs_from_alu
& ~not_rs_from_alu;
/*
* not needed for warthog
*
* New for SUNERGY Puma - all select aligner
wire nrs_from_align =
(d_hop3[8:5]==HMEM | d_hop3[8:4]==HMEMA)
& ~(d_opcode==HLDSTB | d_opcode==HLDSTBA)
;
REGWIRE trs_from_align;
REG(rs_falign_reg,1, trs_from_align, nrs_from_align, ss_clock, hold)
wire rs_from_align = ~ss_scan_mode & ~rdtpc & trs_from_align;
wire rs_from_sh_align = rs_from_sh | rs_from_align;
*/
// DEFAULT
wire rs_from_else = ~rs_from_sh & ~rs_from_alu
& ~force_neg & ~force_pos;
endmodule
/*
* Used to have Mpipe_control here. split into
* Mpipec_im_id, Mpipec_br_vald, Mpipec_help_ilock)
*/
module Mpipec_im_id
(
d_opcode,
e_opcode,
hold,
imul_idiv_ilock,
ss_clock,
valid_decode,
valid_decode_nilock,
w_opcode,
// outs
dhop3_idivbasic,
dhop3_idivbasic_op,
dhop3_imulbasic,
dhop3_imulbasic_op,
dopc_hidiv0_op,
dopc_hidiv1_op,
dopc_hidiv2_op,
dopc_hidiv3_op,
dopc_hidivcc3,
dopc_himul0_op,
dopc_himul1_op,
dopc_himul2_op,
dopc_himulcc2,
ehop3_idivbasic,
ehop3_imulbasic,
eopc_hidiv1,
eopc_hidiv3,
eopc_himul0,
hidiv_in_d,
himul_in_d,
sel_sll1_divalu_l,
signed_div,
signed_mult,
wopc_himul1
);
input [10:0] d_opcode
;
input [10:0] e_opcode
;
input hold
;
input imul_idiv_ilock
;
input ss_clock
;
input valid_decode
;
input valid_decode_nilock
;
input [10:0] w_opcode
;
output dhop3_idivbasic
;
output dhop3_idivbasic_op
;
output dhop3_imulbasic
;
output dhop3_imulbasic_op
;
output dopc_hidiv0_op
;
output dopc_hidiv1_op
;
output dopc_hidiv2_op
;
output dopc_hidiv3_op
;
output dopc_hidivcc3
;
output dopc_himul0_op
;
output dopc_himul1_op
;
output dopc_himul2_op
;
output dopc_himulcc2
;
output ehop3_idivbasic
;
output ehop3_imulbasic
;
output eopc_hidiv1
;
output eopc_hidiv3
;
output eopc_himul0
;
output hidiv_in_d
;
output himul_in_d
;
output sel_sll1_divalu_l
;
output signed_div
;
output signed_mult
;
output wopc_himul1
;
wire [8:0] d_hop3
= d_opcode[10:2];
// some simplifying definitions for IMUL and IDIV
wire dhop3_imulbasic_op =
d_hop3==`UMUL | d_hop3==`UMULCC
| d_hop3==`SMUL | d_hop3==`SMULCC
;
// i know - valid_decode & valid_decode_nilock = valid_decode, but
// this change is in there because this is the way the gates are.
wire dhop3_imulbasic =
valid_decode & ~imul_idiv_ilock & dhop3_imulbasic_op
& valid_decode_nilock;
wire ehop3_imulbasic;
Mflipflop_1 ehop3_imulbasic_reg_1(ehop3_imulbasic,dhop3_imulbasic,ss_clock,hold) ;
wire dhop3_idivbasic_op =
d_hop3==`UDIV | d_hop3==`UDIVCC
| d_hop3==`SDIV | d_hop3==`SDIVCC
;
wire dhop3_idivbasic =
valid_decode & ~imul_idiv_ilock & dhop3_idivbasic_op
& valid_decode_nilock;
wire ehop3_idivbasic;
Mflipflop_1 ehop3_idivbasic_reg_1(ehop3_idivbasic,dhop3_idivbasic,ss_clock,hold) ;
wire dopc_himul0_op =
d_opcode==`HUMUL0 | d_opcode==`HUMULCC0
| d_opcode==`HSMUL0 | d_opcode==`HSMULCC0
;
wire eopc_himul0;
Mflipflop_1 eopc_himul0_reg_1(eopc_himul0,dopc_himul0_op,ss_clock,hold) ;
wire dopc_hidiv0_op =
d_opcode==`HUDIV0 | d_opcode==`HUDIVCC0
| d_opcode==`HSDIV0 | d_opcode==`HSDIVCC0
;
wire dopc_himul1_op =
d_opcode==`HUMUL1 | d_opcode==`HUMULCC1
| d_opcode==`HSMUL1 | d_opcode==`HSMULCC1
;
wire dopc_hidiv1_op =
d_opcode==`HUDIV1 | d_opcode==`HUDIVCC1
| d_opcode==`HSDIV1 | d_opcode==`HSDIVCC1
;
wire eopc_hidiv1 =
e_opcode==`HUDIV1 | e_opcode==`HUDIVCC1
| e_opcode==`HSDIV1 | e_opcode==`HSDIVCC1
;
wire sel_sll1_divalu_l = ~eopc_hidiv1;
wire wopc_himul1 =
w_opcode==`HUMUL1 | w_opcode==`HUMULCC1
| w_opcode==`HSMUL1 | w_opcode==`HSMULCC1
;
wire dopc_himul2_op =
d_opcode==`HUMUL2 | d_opcode==`HUMULCC2
| d_opcode==`HSMUL2 | d_opcode==`HSMULCC2
;
wire dopc_himulcc2 =
d_opcode==`HUMULCC2 | d_opcode==`HSMULCC2
;
wire dopc_hidiv2_op =
d_opcode==`HUDIV2 | d_opcode==`HUDIVCC2
| d_opcode==`HSDIV2 | d_opcode==`HSDIVCC2
;
wire dopc_hidiv3_op =
d_opcode==`HUDIV3 | d_opcode==`HUDIVCC3
| d_opcode==`HSDIV3 | d_opcode==`HSDIVCC3
;
wire dopc_hidivcc3 =
d_opcode==`HUDIVCC3 | d_opcode==`HSDIVCC3
;
wire eopc_hidiv3 =
e_opcode==`HUDIV3 | e_opcode==`HUDIVCC3
| e_opcode==`HSDIV3 | e_opcode==`HSDIVCC3
;
wire himul_in_d =
dopc_himul0_op | dopc_himul1_op
| dopc_himul2_op
;
wire hidiv_in_d =
dopc_hidiv0_op | dopc_hidiv1_op
| dopc_hidiv2_op | dopc_hidiv3_op
;
wire signed_mult =
d_hop3==`SMUL | d_hop3==`SMULCC
| d_opcode==`HSMUL0 | d_opcode==`HSMULCC0
| d_opcode==`HSMUL1 | d_opcode==`HSMULCC1
| d_opcode==`HSMUL2 | d_opcode==`HSMULCC2
;
wire signed_div =
d_hop3==`SDIV | d_hop3==`SDIVCC
| d_opcode==`HSDIV0 | d_opcode==`HSDIVCC0
| d_opcode==`HSDIV1 | d_opcode==`HSDIVCC1
| d_opcode==`HSDIV2 | d_opcode==`HSDIVCC2
| d_opcode==`HSDIV3 | d_opcode==`HSDIVCC3
;
endmodule
module Mpipec_br_vald
(
TRAP,
bicc_taken,
d_anl,
d_cond,
d_hop2,
d_nop,
d_trap,
del_resetm,
e_help,
fold_annul,
hold,
interlock,
interlock_vald,
iacc_exc_mmumiss_d,
mispredicted,
pfcc,
reset,
ss_clock,
trapd_iaer,
untaken_empty_ilock,
// outs
ANNUL,
nANNUL,
bcop_taken,
fcc_taken,
hnop_into_ex,
clr_e_iexc_nop,
valid_decode,
valid_decode_nilock
);
input TRAP
;
input bicc_taken
;
input d_anl
;
input [3:0] d_cond
;
input [5:0] d_hop2
;
input d_nop
;
input d_trap
;
input del_resetm
;
input e_help
;
input fold_annul
;
input hold
;
input interlock
;
input interlock_vald
;
input iacc_exc_mmumiss_d
;
input mispredicted
;
input [1:0] pfcc
;
input reset
;
input ss_clock
;
input trapd_iaer
;
input untaken_empty_ilock
;
output ANNUL
;
output nANNUL
;
output bcop_taken
;
output fcc_taken
;
output hnop_into_ex
;
output clr_e_iexc_nop
;
output valid_decode
;
//output valid_decode_imh;
//output valid_decode_nil_imh;
output valid_decode_nilock
;
//FORWARD DEC.
wire ANNUL;
// FCC evaluation
wire fcc_taken;
Mfcc_eval fcc_eval(fcc_taken, d_cond, pfcc);
wire bcop_taken;
assign bcop_taken = fcc_taken;
// control for inserting HNOP into ex.
wire p_reset
;
Mflipflop_1 p_reset_reg_1(p_reset,reset,ss_clock,1'b0) ;
assign hnop_into_ex = (del_resetm | iacc_exc_mmumiss_d | d_nop
| interlock | TRAP | ANNUL
| trapd_iaer
| (p_reset & ~reset)
| mispredicted & ~d_hop2[5]
| fold_annul & d_hop2[5]
)
& ~d_trap;
wire clr_e_iexc_nop = (del_resetm | d_nop
| interlock | TRAP | ANNUL
| (p_reset & ~reset)
| mispredicted & ~d_hop2[5]
| fold_annul & d_hop2[5]
)
& ~d_trap;
// the mispredicted and fold_annul terms are in hnop_into_ex
// for a reason. when we mispredict, if the delay slot is
// a multicycle instruction, we should *not* kill the help
// cycle going to E. when we annul, if the delay slot was
// a multicycle instruction, we should annul the help going
// to E.
// control for inserting HTRAP into ex
/*
* See after instanciation of Mpipe_control for htrap_into_ex
assign htrap_into_ex = d_trap;
*
*/
// ANULLING CONTROL
// Not for SUNERGY Puma
/* detect annuling when
BICC,a in execute and ~bicc_taken OR
BA,a in execute OR
BFCC,a in execute and ~bcop_taken OR
FBA,a in execute OR
BCCC,a in execute and ~bcop_taken OR
CBA,a in execute
When detected the following must happen:
force HNOP into execute next cycle
activate d_no_write
prevent gen_help
*/
/*
* For SUNERGY Puma
Detect annuling when
BICC,a in decode and ~bicc_taken OR
BA,a in decode OR
BFCC,a in decode and ~bcop_taken OR
FBA,a in decode OR
BCCC,a in decode and ~bcop_taken OR
CBA,a in decode
When detect annul, need to pipeline ANNUL into the ANNULled
instruction's D cycle (detect annul is done in the annulled
inst.'s F cycle).
*
*/
/* detect BICC,a in decode and pipeline to annulling cycle */
wire d_hop2bicc
= d_hop2==`BICC;
// wire nimight_annul = valid_decode & d_hop2bicc & d_anl;
wire nimight_annul
= d_hop2bicc;
/* same for BFCC,a and BCCC,a */
wire d_hop2bfccc
= (d_hop2==`BFCC);
// wire ncmight_annul = valid_decode & d_hop2bfccc & d_anl;
wire ncmight_annul
= d_hop2bfccc;
/* detect BA,a FBA,a and CBA,a and pipeline to the next decode cycle */
wire d_hop2bifccc
= (d_hop2==`BICC | d_hop2==`BFCC);
wire d_condbr_always
= d_cond==`BR_ALWAYS;
// wire nwill_annul = valid_decode & d_condbr_always & d_hop2bifccc & d_anl;
wire nwill_annul
= d_condbr_always & d_hop2bifccc;
/*
* New for SUNERGY Puma
* ANNUL is still asserted in the D cycle of the delay instruction
* It is just detected in D of the branch and piped to here.
*/
wire nANNUL =
valid_decode & d_anl & (
nwill_annul
| (nimight_annul & ~bicc_taken)
| (ncmight_annul & ~bcop_taken)
)
| ANNUL & untaken_empty_ilock;
wire ANNUL_almost
;
Mflipflop_1 annul_reg_1( ANNUL_almost, nANNUL, ss_clock, hold) ;
assign ANNUL = ANNUL_almost & ~fold_annul;
// NULLIFY DECODE
/* In many instances where the decode opcodes are looked at, the
logic must be modified by consideration of situations
which occur in decode that are not reflected in the opcode.
These situations in general cause the instruction to
be annulled through the rest of the pipe
*/
wire d_help
= d_hop2[5];
wire kill_help_d
= ~e_help & d_help & fold_annul;
wire kill_nohelp_d
= ~d_help & mispredicted;
wire valid_decode_
=
d_nop | iacc_exc_mmumiss_d | interlock_vald | d_trap | ANNUL
| mispredicted & ~d_help
| kill_help_d
| kill_nohelp_d
// | (imhold & null_in_d)
// | trapd_iaer
;
/*
* same as valid_decode
wire valid_decode_imh_ =
d_nop | iacc_exc_mmumiss_d | interlock | d_trap | ANNUL
| mispredicted & ~d_help
| kill_help_d
| kill_nohelp_d
// | (ic_sustain_imhold & null_in_d)
;
*/
wire valid_decode_nilock_l
=
d_nop | iacc_exc_mmumiss_d | d_trap | ANNUL
| mispredicted & ~d_help
| kill_help_d
| kill_nohelp_d
// | (imhold & null_in_d)
// | trapd_iaer
;
/*
* same as valid_decode_nilock
wire valid_decode_nil_imh_l =
d_nop | iacc_exc_mmumiss_d | d_trap | ANNUL
| mispredicted & ~d_help
| kill_help_d
| kill_nohelp_d
// | (ic_sustain_imhold & null_in_d)
;
*/
// do we really need to put ~reset here?
assign valid_decode = ~valid_decode_;
wire valid_decode_nilock = ~valid_decode_nilock_l;
// wire valid_decode_nil_imh = ~valid_decode_nil_imh_l;
// wire valid_decode_imh = ~valid_decode_imh_;
/* For the FPC, need a form of valid_decode that does not
have the fhold_ilock term in interlock. See interlock_fpu.
*/
/*
* not needed for Warthog
wire valid_decode_fpu_ =
interlock_fpu | ANNUL | d_nop | d_trap | iacc_exc_mmumiss_d
// | trapd_iaer
;
wire valid_decode_fpu = ~valid_decode_fpu_;
*/
endmodule
module Mpipec_help_ilock
(
ANNUL,
ER_SDOUT,
ERROR_nop,
b1_eq_src1,
b1_eq_src2,
d_imm,
d_opcode,
d_rs1,
d_rs2,
d_trap,
dhop3_idivbasic_op,
dhop3_imulbasic_op,
dopc_hidiv0_op,
dopc_hidiv1_op,
dopc_hidiv2_op,
dopc_himul0_op,
dopc_himul1_op,
drd_eq_erd,
e_hldd,
e_load,
e_no_write,
e_hop,
e_rdpsr_op,
e_rdtbr_op,
e_rdwim_op,
e_rdy_op_forilock,
ef,
dfrd_eq_efrd,
fold_annul,
hold,
iacc_exc_mmumiss_d,
mispredicted,
ndet_divovf,
pfccv,
r_no_write,
rd_ex_g0,
reset,
ss_clock,
untaken_empty_ilock,
sv_rest_fold_ilock,
valid_decode,
valid_decode_nilock,
w_no_write,
// outs
d_nop,
fcc_ilock,
gen_help,
gen_help_op,
help_ctr,
imul_idiv_ilock,
interlock,
interlock_vald,
iu_fetch_f,
next_d_hhn
);
input ANNUL
;
input ER_SDOUT
;
input ERROR_nop
;
input b1_eq_src1
;
input b1_eq_src2
;
input d_imm
;
input [10:0] d_opcode
;
input [4:0] d_rs1
;
input [4:0]d_rs2
;
input d_trap
;
input dhop3_idivbasic_op
;
input dhop3_imulbasic_op
;
input dopc_hidiv0_op
;
input dopc_hidiv1_op
;
input dopc_hidiv2_op
;
input dopc_himul0_op
;
input dopc_himul1_op
;
input drd_eq_erd
;
input e_hldd
;
input e_load
;
input e_no_write
;
input [2:0] e_hop
;
input e_rdpsr_op
;
input e_rdtbr_op
;
input e_rdwim_op
;
input e_rdy_op_forilock
;
input ef
;
input dfrd_eq_efrd
;
input fold_annul
;
input hold
;
input iacc_exc_mmumiss_d
;
input mispredicted
;
input ndet_divovf
;
input pfccv
;
input r_no_write
;
input rd_ex_g0
;
input reset
;
input ss_clock
;
input untaken_empty_ilock
;
input sv_rest_fold_ilock
;
input valid_decode
;
input valid_decode_nilock
;
input w_no_write
;
output d_nop
;
output fcc_ilock
;
output gen_help
;
output gen_help_op
;
output [5:0] help_ctr
;
output imul_idiv_ilock
;
output interlock
;
output interlock_vald
;
output iu_fetch_f
;
//output jmp_ilock;
output [2:0] next_d_hhn
;
wire d_nop;
wire [5:0] d_hop2
= d_opcode[10:5];
wire [8:0] d_hop3
= d_opcode[10:2];
// Help counter for IMUL and IDIV since there are so many
// damn help cycles
wire [5:0] help_ctr;
wire [5:0] nhelp_ctr
;
wire [5:0] help_count_out
= help_ctr + 6'b000001;
wire nhelp_ctr_sel
= ~fold_annul & ~reset & (
| dopc_himul0_op
| dopc_hidiv0_op & ~(help_ctr[1]==1'b1)
| dopc_hidiv1_op
)
;
// Expanded macro begin.
// cmux2(nhelp_ctr_mux, 6, nhelp_ctr, 6'b0, help_count_out, nhelp_ctr_sel)
function [6:1] nhelp_ctr_mux ;
input [6:1] in0_fn ;
input [6:1] in1_fn ;
input select_fn ;
reg [6: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
nhelp_ctr_mux = out_fn ;
end
endfunction
assign nhelp_ctr = nhelp_ctr_mux( 6'b0, help_count_out, nhelp_ctr_sel) ;
// Expanded macro end.
Mflipflop_6 help_ctr_reg_6(help_ctr,nhelp_ctr,ss_clock,hold) ;
// does the instruction generate another help?
// STA is a single cycle instruction, but STA to
// I$ (either I$ access or flush asi) will cause
// the CC to hold the pipe the cycle *after*
// the IU generate force_dva. the same is true
// for IFLUSH
wire gen_help_op =
d_hop3==`JMP | d_hop3==`RETT
| d_hop3==`LDA
| d_hop3==`LDD | d_hop3==`LDDA
| d_hop3==`STD | d_hop3==`STDA
| d_hop3==`LDSTB | d_hop3==`LDSTBA
| d_hop3==`SWAP | d_hop3==`SWAPA
| d_hop3==`STA // | d_opcode==HSTA0
| d_hop3==`IFLUSH // | d_opcode==HIFLUSH0
| dhop3_imulbasic_op
| dopc_himul0_op | dopc_himul1_op
| dhop3_idivbasic_op
| dopc_hidiv0_op | dopc_hidiv1_op
| dopc_hidiv2_op
;
/*
* not muticycle inst anymore
| d_hop3==LDDF
| d_hop3==STB | d_hop3==STBA
| d_hop3==STH | d_hop3==STHA
| d_hop3==ST | d_hop3==STA
| d_opcode==HSTD0 | d_opcode==HSTDA0
| d_hop3==STDFQ | d_opcode==HSTDFQ0
| d_hop3==STF
| d_hop3==STDF | d_opcode==HSTDF0
| d_hop3==STFSR
*/
/*
* incorporated into valid_decode instead
wire d_help = d_opcode[10];
wire e_help = e_opcode[10];
wire kill_help_fold = ~e_help & d_help & fold_annul;
*/
wire gen_help = valid_decode & gen_help_op; // & ~kill_help_fold
// synopsys translate_off
wire pgen_help
;
Mflipflop_1 pgenhelp_ff_1( pgen_help, gen_help, ss_clock, hold) ;
// synopsys translate_on
// value of next help opcode bits
wire iu_fetch_f =
~gen_help & ~reset // & ~hold
& ~(interlock & valid_decode_nilock)
& ~untaken_empty_ilock
& ~ER_SDOUT
;
// don't think i need this one either....
// & ~iacc_exc_mmumiss_d
// NEED TO THINK ABOUT THIS ONE
// & ~(imhold & e_opcode==HIFLUSH3)
// this one too....
// & ~TRAP & ~trap_cyc1
// synopsys translate_off
wire iu_fetch_dq
;
Mflipflop_1 iu_fetch_d_reg_1(iu_fetch_dq,iu_fetch_f,ss_clock,hold) ;
wire iu_fetch_d
= iu_fetch_dq & ~iacc_exc_mmumiss_d;
// synopsys translate_on
/*
* next_d_hhn
*/
assign next_d_hhn = {
gen_help,
dopc_himul1_op
| dopc_hidiv1_op & (help_ctr[5] == 1'b1)
| dopc_hidiv1_op & (help_ctr==6'b000000) & ndet_divovf
| dopc_hidiv2_op,
(dopc_himul0_op & help_ctr==6'b001111)
| dopc_hidiv1_op & ~(help_ctr[5] == 1'b1)
| dopc_hidiv2_op
This page: |
Created: | Thu Aug 19 11:57:27 1999 |
| From: |
../../../sparc_v8/ssparc/iu/Mdecode/rtl/decode.v
|