// pipeline into the EX cycle
wire e_no_write_almost
;
Mflipflop_1 e_no_write_reg_1( e_no_write_almost, d_no_write, ss_clock, hold) ;
wire e_no_write = e_no_write_almost | fold_annul;
// pipeline into WR cycle
wire w_no_write;
Mflipflop_1 w_no_write_reg_1( w_no_write, e_no_write, ss_clock, hold) ;
wire result_r0 = (w_no_write | TRAP) & ~d_trap;
// force %g0 into rd_rslt
// pipeline into RS cycle
wire next_r_nowrite
= (w_no_write | TRAP) & ~trap_cyc2;
// the trap_cyc2 term below allows bypass 3 to work if the
// 1st instruction of the trap-handler reads the 2nd (NPC)
// trap address
wire r_no_write;
Mflipflop_1 r_no_write_reg_1( r_no_write, next_r_nowrite, ss_clock, hold) ;
/************************************************************/
// RF WRITE DATA SELECTOR
wire wr_lddata_w
=
w_hop3==`LDSB | w_hop3==`LDUB | w_hop3==`LDSH | w_hop3==`LDUH
| w_hop3==`LD
| w_hop3==`LDSBA | w_hop3==`LDUBA
| w_hop3==`LDSHA | w_hop3==`LDUHA
| w_hop3==`LDA
| w_hop3==`SWAP | w_hop3==`SWAPA
| w_hop3==`LDSTB | w_hop3==`LDSTBA
| w_hop3==`LDD | w_hop3==`LDDA
| w_opcode==`HLDD | w_opcode==`HLDDA
;
// REGWIRE re_lddata_r;
// REG(re_lddata_r_reg,1,re_lddata_r,wr_lddata_w,ss_clock,hold)
wire wr_lddatam
=
wr_lddata_w
// | (re_lddata_r & dc_sustain_dmhold & ~got_data)
;
wire wr_lddatam_l = ~wr_lddatam;
// REGISTER FILE WRITE ENABLE
// disable the register file write during mhold and during any
// data write cycle in which an exception is indicated for
// the access.
//grp dum grpNEXTADR1 out grpNEXTADR1
/*
* this are the conditions when we DO NOT write the RF
wire hold_rf =
ss_scan_mode
| mm_start_dmhold
| dc_sustain_dmhold & hold & ~got_data
| mm_dacc_exc_r
| reset;
// | dt_perror
// for tsunami
wire almost_rf_we =
~(ss_scan_mode
| mm_start_dmhold
| dc_sustain_dmhold & hold & ~got_data
| dacc_exc_err_mmumiss_r
| reset)
| do_frfon;
*/
// This free running register normally has 0 in it. it can
// be set to 1 using the scan chain. this will force
// the rf_we_w ON when scan_mode turns off. the advantage
// to this is that it allows us to turn on the rf_we easier.
wire force_rfon
;
Mflipflop_1 force_rfon_reg_1(force_rfon,1'b0,ss_clock,1'b0) ;
wire do_frfon
= force_rfon & ~ss_scan_mode;
wire rf_we_w =
~(ss_scan_mode // need D$ exc term here too
| reset)
| do_frfon
;
// Generate a hold signal to prevent strobing in multiple data
// words during a dmhold. Usually, only the first d_data_avail
// is recognized - however, a second one is used to strobe
// the second word of a ldd.
/*
wire hold_r_reg =
hold; // & ~(d_data_avail & ~got_data);
*/
// generate correct alus1_datam and alus2_datam in the event of
// ld miss and the instruction following it uses the destination
// register of the load. need to strobe in the load data to the
// alu source registers.
/* REGWIRE palus1_datam_normal;
REGWIRE palus2_datam_normal;
REG(alus1_datam_normal_reg,1,palus1_datam_normal, alus1_datam_normal,ss_clock,hold)
REG(alus2_datam_normal_reg,1,palus2_datam_normal, alus2_datam_normal,ss_clock,hold)
wire alus1_datam =
~ss_scan_mode &
(alus1_datam_normal
| palus1_datam_normal & dc_sustain_dmhold & ~got_data
)
;
wire alus2_datam =
~ss_scan_mode &
(alus2_datam_normal
| palus2_datam_normal & dc_sustain_dmhold & ~got_data
)
;
*/
// don't know where to put this, so put it here. used to
// select the basic operand thru the last src2 mux (as opposed
// to the load data or clear to 0)
wire rs2_passit =
~alus2_datam & ~rs2_clear
;
// Hold rs2 during HIMUL2
wire hold_rs2
= dopc_himul2_op;
// also need to generate strobes for the alu source registers
// to get the data in.
/*
* not needed for warthog
wire alu_s1_reg_hold =
hold & ~(palus1_datam_normal & dc_sustain_dmhold
& d_data_avail & ~got_data)
;
*/
wire alu_s2_reg_hold = hold_rs2;
// hold | hold_rs2
// ;
// hold & ~(palus2_datam_normal & dc_sustain_dmhold
// & d_data_avail & ~got_data)
/*
* moved to D$
// LOAD ALIGNER CONTROLS
wire sbytem =
(w_hop3==LDSB | w_hop3==LDSBA) // & ~dc_sustain_dmhold
;
wire ubytem =
(w_hop3==LDUB | w_hop3==LDUBA
| w_hop3==LDSTB | w_hop3==LDSTBA)
;
wire shalfm =
(w_hop3==LDSH | w_hop3==LDSHA)
;
wire uhalfm =
(w_hop3==LDUH | w_hop3==LDUHA)
;
wire wordm =
~(sbytem | ubytem | uhalfm | shalfm);
wire byte0m =
(which_byte_ == 2'b11)
;
wire byte1m =
(which_byte_ == 2'b10)
;
wire byte2m =
(which_byte_ == 2'b01)
;
wire byte3m =
(which_byte_ == 2'b00)
;
//logic for select of load aligner
wire m3b3 = wr_lddatam & (wordm | ((shalfm | uhalfm) & byte2m)
| ((sbytem | ubytem) & byte3m));
wire m3b2 = wr_lddatam & (sbytem | ubytem) & byte2m;
wire m3b1 = wr_lddatam & (((shalfm | uhalfm) & byte0m)
| ((sbytem | ubytem) & byte1m));
wire m3b0 = wr_lddatam & (sbytem | ubytem) & byte0m;
wire m20 = wr_lddatam & ubytem;
wire m2b2 = wr_lddatam & (wordm | ((shalfm | uhalfm) & byte2m));
wire m2b0 = wr_lddatam & (shalfm | uhalfm) & byte0m;
wire m2s0 = wr_lddatam & sbytem & byte0m;
wire m2s2 = wr_lddatam & sbytem & byte2m;
wire m0m10 = wr_lddatam & (ubytem | uhalfm);
wire m0m1b0b1 = wr_lddatam & wordm;
wire m0m1s0 = wr_lddatam & (sbytem | shalfm)& byte0m;
wire m0m1s2 = wr_lddatam & (sbytem | shalfm)& byte2m;
wire m0m1m2s1 = wr_lddatam & sbytem & byte1m;
wire m0m1m2s3 = wr_lddatam & sbytem & byte3m;
*/
endmodule
module Malu_control
(
TRAP,
alu_cc_carry,
alu_cc_zero,
alu_s1m_0,
alu_s1s_lsb2,
alu_s2m_5_0_0,
alu_s2m_5_1,
alus1_b1m,
alus1_b2m,
alus1_datam,
alus1_set,
alus2_b1m,
alus2_b2m,
alus2_datam,
ccm_lo_0,
ss_clock,
d_imm,
d_opcode,
d_rs2_lo,
dhop3_idivbasic_op,
dhop3_imulbasic_op,
dopc_hidiv0_op,
dopc_hidiv1_op,
dopc_hidiv2_op,
dopc_hidiv3_op,
dopc_himul0_op,
dopc_himul1_op,
e_hop3,
ehop3_imulbasic,
eopc_hidiv3,
eopc_himul0,
nfold_annul,
help_ctr,
hidiv_in_d,
high_2_1,
idiv_shiftin_low,
himul_in_d,
hold,
nERROR,
rd_wr_g0,
trap_cyc1,
reset,
result31,
result_lo0,
dsign_bit2,
rf2_imm_data_msb,
dsign_bit1,
setcc,
signed_div,
signed_mult,
msign_bit,
src1m_msb,
src2m_lo,
ss_scan_mode,
valid_decode,
valid_decode_nilock,
w_hop3,
wopc_himul1,
ym,
alu_ADD,
alu_AND,
alu_XNOR,
alu_sub,
tagged_ovf,
alus1_b2_shift,
alus1_rfm_b3m,
a2top_default,
carry_in,
pass_hi_rs1,
det_divovf,
ne_mulsm,
next_e_not_negmul,
hld_y,
hold_Wreg,
n_ymsb,
ndet_divovf,
rs1_clear,
rs1_double,
nrs1_negate,
nrs1_negate_l,
rs1_pass,
spc_mux_default,
rs2_clear,
rs_from_alu,
rs_from_else,
rs_from_sh,
sel_rs1_shiftin,
sel_srl2_mult,
nsel_w_mult,
nsel_w_mult_l_b,
nsel_w_mult_l_not_b,
wr_y,
wr_mulscc,
use_hi_alu,
use_hi_rs1_default,
use_hi_rs2,
use_hi_rs2_default,
not_rs2_rs1_default,
use_hi_y,
shift_left,
arith_shift,
force_neg,
force_pos
);
input TRAP
;
input alu_cc_carry
;
input alu_cc_zero
;
input alu_s1m_0
;
input [1:0] alu_s1s_lsb2
;
input alu_s2m_5_0_0
;
input [5:1] alu_s2m_5_1
;
input alus1_b1m
;
input alus1_b2m
;
input alus1_datam
;
input alus1_set
;
input alus2_b1m
;
input alus2_b2m
;
input alus2_datam
;
input ccm_lo_0
;
input ss_clock
;
input d_imm
;
input [10:0] d_opcode
;
input [3:0] d_rs2_lo
;
input dhop3_idivbasic_op
;
input dhop3_imulbasic_op
;
input dopc_hidiv0_op
;
input dopc_hidiv1_op
;
input dopc_hidiv2_op
;
input dopc_hidiv3_op
;
input dopc_himul0_op
;
input dopc_himul1_op
;
input [8:0] e_hop3
;
input ehop3_imulbasic
;
input eopc_hidiv3
;
input eopc_himul0
;
input nfold_annul
;
input [5:0] help_ctr
;
input hidiv_in_d
;
input high_2_1
;
output idiv_shiftin_low
;
input himul_in_d
;
input hold
;
input nERROR
;
input rd_wr_g0
; // is dest reg of inst in W %g0?
//input rdtpc;
input trap_cyc1
;
input reset
;
input result31
;
input result_lo0
;
output dsign_bit2
;
input rf2_imm_data_msb
;
output dsign_bit1
;
input setcc
;
input signed_div
;
input signed_mult
;
output msign_bit
;
input src1m_msb
;
input [3:0] src2m_lo
;
input ss_scan_mode
;
input valid_decode
;
input valid_decode_nilock
;
input [8:0] w_hop3
;
input wopc_himul1
;
input [2:0] ym
;
output alu_ADD
;
output alu_AND
;
output alu_XNOR
;
output alu_sub
;
output tagged_ovf
;
output alus1_b2_shift
;
output alus1_rfm_b3m
;
// output alus2_rfm;
output a2top_default
;
output carry_in
;
output pass_hi_rs1
;
output det_divovf
;
output ne_mulsm
;
output next_e_not_negmul
;
output hld_y
;
output hold_Wreg
;
output n_ymsb
;
output ndet_divovf
;
output rs1_clear
;
output rs1_double
;
output nrs1_negate
;
output nrs1_negate_l
;
output rs1_pass
;
output spc_mux_default
;
output rs2_clear
;
output rs_from_alu
;
output rs_from_else
;
output rs_from_sh
;
output sel_rs1_shiftin
;
output sel_srl2_mult
;
output nsel_w_mult
;
output nsel_w_mult_l_b
;
output nsel_w_mult_l_not_b
;
output wr_y
;
output wr_mulscc
;
output use_hi_alu
;
output use_hi_rs1_default
;
output use_hi_rs2
;
output use_hi_rs2_default
;
output not_rs2_rs1_default
;
output use_hi_y
;
//output [4:0] shift_cnt;
output shift_left
;
output arith_shift
;
output force_neg
;
output force_pos
;
wire [4:0] alu_s2i_cnt
= {alu_s2m_5_1[4:1],alu_s2m_5_0_0};
//FORWARD DEC.
wire det_divovf;
wire shift_pm
;
wire zr_add_term
;
wire [2:0] factor_sel
;
wire shift_passm
;
wire div_inv_bit
;
wire final_sgn
;
reg ndet_divovf;
wire nfinal_sgn
;
wire [2:0] d_hop
= d_opcode[10:8];
wire [5:0] d_hop2
= d_opcode[10:5];
wire [8:0] d_hop3
= d_opcode[10:2];
/*
* not needed cuz st alignment is done in RF
// STORE ALIGNMENT SHIFT AMOUNT
wire nbyte_align = d_opcode==HSTB | d_opcode==HSTBA;
wire nhalf_align = d_opcode==HSTH | d_opcode==HSTHA;
wire nshift_st4 =
(nbyte_align & ~nadr_align[1])
| (nhalf_align & nadr_align==2'b00)
;
REGWIRE shift_st4;
REG(shift_amt4_reg,1, shift_st4, nshift_st4,ss_clock,hold)
wire nshift_st3 =
nbyte_align & ~nadr_align[0];
REGWIRE shift_st3;
REG(shift_amt3_reg,1,shift_st3, nshift_st3, ss_clock,hold)
*/
// DEFAULT ALU SOURCE CONTROLS
// SRC 1
wire alus1_rfm
=
~alus1_b1m & ~alus1_b2m // & ~alus1_b3m
& ~alus1_set // & ~alus1_datam
& ~sel_rs1_shiftin
& ~alus1_b2_shift
;
wire alus1_rfm_b3m = alus1_rfm;
// SRC 2
// wire alus2_rfm = ~alus2_b1m & ~alus2_b2m // & ~alus2_b3m
// & ~alus2_datam // & ~d_imm
// & ~sel_srl2_mult;
wire a2top_default = ~alus2_b1m & ~alus2_b2m & ~sel_srl2_mult;
wire dsign_bit1 = result31 & signed_div;
wire hld_dsb2
= ~(dhop3_idivbasic_op & valid_decode) & ~reset
| hold;
wire ndsign_bit2
= rf2_imm_data_msb & signed_div & valid_decode;
wire dsign_bit2;
Mflipflop_1 dsign_bit2_reg_1(dsign_bit2,ndsign_bit2,ss_clock,hld_dsb2) ;
// ADDRESS ADDER CONTROLS
// all opcodes which generate an address.
// LOGIC
// it is necessary to qualify this control with
// all of the components of almost_valid:
// d_nop, d_trap and mm_iacc_exc_d to prevent
// random addresses from being generated.
// ANNUL so that annuling loads and stores
// will prevent a data address from getting out.
/*
* IFLUSH - detect in W and pipe to R. take IFLUSH only when
IFT field of XCR = 0.
wire iu_iflush_w =
(w_hop3 == IFLUSH)
& ~reset & ~nERROR & ~TRAP;
*
*/
// MULScc CONTROL
wire ne_muls_op
= d_hop3==`MULSCC;
wire ne_mulsm = ne_muls_op & valid_decode & ~nfold_annul;
// also register in exec DP now
wire e_mulsm
;
Mflipflop_1 ex_muls_ms_1( e_mulsm, ne_mulsm, ss_clock, hold) ;
wire w_hop3mulscc
= w_hop3==`MULSCC;
wire w_muls
= w_hop3mulscc & ~TRAP;
// new MSB on MULScc instruction
// this has been moved to the exec unit. see shiftin_a.
// wire shiftin_am = (Nm & ~Vm) | (~Nm & Vm);
// WRY CONTROL
wire w_hop3wry
=
w_hop3==`WRY
| wopc_himul1
;
wire shift_y
= (~w_hop3wry | TRAP); //& ~ss_scan_mode
wire wr_y = ~shift_y; // & ~ss_scan_mode
wire wr_mulscc = shift_y; // & ~ss_scan_mode
// added ~rd_wr_g0 & w_hop3==WRY - prevents IU from writing
// Yreg on WRASR/WRMODES instructions. These decode as
// a WRY, but their rd fields are non-zero.
wire hld_y = shift_y & ~w_muls
| ~rd_wr_g0 & w_hop3==`WRY; // & ~ss_scan_mode
// PIPELINE alu_s10 because MULScc Shift is done in W-cycle
// - after the add
wire n_ymsb;
Mflipflop_1 nymsb_ff_1( n_ymsb, alu_s1m_0, ss_clock, hold | ss_scan_mode) ;
// ALU CONTROLS
wire nalu_pass_op
= // next alu_pass
d_hop3==`MULSCC;
wire y0_formuls
=
ym[0] & ~wopc_himul1
| result_lo0 & wopc_himul1
;
wire nmuls_add
=
(y0_formuls & ~e_mulsm & ~w_muls)
| (ym[1] & (e_mulsm & ~w_muls | ~e_mulsm & w_muls))
| (ym[2] & e_mulsm & w_muls)
;
wire nalu_pass
=
nalu_pass_op & ~nmuls_add | d_hop2==`SETHI;
wire nalu_and_op
= // next alu_AND
d_hop3==`AND | d_hop3==`ANDCC | d_hop3==`ANDN | d_hop3==`ANDNCC;
wire nalu_AND
=
nalu_and_op | nalu_pass;
wire alu_AND;
Mflipflop_1 alu_and_ff_1( alu_AND, nalu_AND, ss_clock, hold) ;
wire nalu_or
= // next alu_or
d_hop3==`OR | d_hop3==`ORCC | d_hop3==`ORN | d_hop3==`ORNCC;
wire nalu_xnor_op
= // next alu_xnor
d_hop3==`XOR | d_hop3==`XORCC | d_hop3==`XNOR | d_hop3==`XNORCC
| d_hop3[8:2]==`WR; // WRPSR etc.
wire nalu_XNOR
=
nalu_xnor_op | nalu_pass;
wire alu_XNOR;
Mflipflop_1 alu_xnor_ff_1( alu_XNOR, nalu_XNOR, ss_clock, hold) ;
wire nalu_ADD
= // next alu_add
~nalu_AND & ~nalu_XNOR & ~nalu_or;
wire alu_ADD;
Mflipflop_1 alu_add_ff_1( alu_ADD, nalu_ADD, ss_clock, hold) ;
// Note that sgnA and sgnB have been removed as being too slow.
// i have replaced them with new_sgnA and high_2_1 as equivalents
// to sgnA, each used at the appropriate time. sgnB has been
// replaced by dsign_bit2 as a direct replacement.
wire new_sgnA
= result31 & signed_div;
wire nsubtractb_idiv
=
dopc_hidiv1_op
& help_ctr==6'b000000 & ~(new_sgnA ^ dsign_bit2)
| dopc_hidiv1_op
& help_ctr>6'b0 & ~(high_2_1 ^ dsign_bit2)
| dopc_hidiv0_op & help_ctr[1]==1'b1
& ~(new_sgnA ^ dsign_bit2)
;
wire nalu_invertb_almost
= // invert B input
d_hop3==`SUB | d_hop3==`SUBCC | d_hop3==`SUBX | d_hop3==`SUBXCC
| d_hop3==`TSUBCC | d_hop3==`TSUBCCTV
| d_hop3==`ANDN | d_hop3==`ANDNCC
| d_hop3==`OR | d_hop3==`ORCC
| d_hop3==`XOR | d_hop3==`XORCC
| d_hop3[8:2]==`WR
| dopc_hidiv3_op & ~det_divovf & div_inv_bit
;
// took nsubtractb_idiv out of above in order to force synopsys
// to bring the sgnA term into nalu_invertb as deep as possible
// in the logic tree to lessen the required setup time.
wire nalu_invertb
= nalu_invertb_almost | nsubtractb_idiv;
// REGWIRE alu_invertbm;
// REG(alu_inv_ms,1, alu_invertbm, nalu_invertb, // ss_clock, hold)
wire nsel_w_mult;
wire nsel_w_mult_l_b = ~nsel_w_mult & ~nalu_invertb;
wire nsel_w_mult_l_not_b = ~nsel_w_mult & nalu_invertb;
wire nalu_sub
= nalu_ADD & nalu_invertb; // subtract (invert C)
// pipeline into Execute
wire alu_sub;
Mflipflop_1 alu_sub_ff_1(alu_sub, nalu_sub, ss_clock, hold) ;
// ALU CARRY_IN CONTROL
wire nwith_carry
= // next with_carry
d_hop3==`ADDX | d_hop3==`ADDXCC
| d_hop3==`SUBX | d_hop3==`SUBXCC
;
wire nforce_carry_most
= // next force_carry
d_hop3==`SUB | d_hop3==`SUBCC
| d_hop3==`TSUBCC | d_hop3==`TSUBCCTV
| (dopc_himul0_op & factor_sel[2]
& ~(factor_sel[1] & factor_sel[0]))
| dopc_hidiv3_op & zr_add_term & ~det_divovf
| dopc_hidiv3_op & det_divovf & ~final_sgn &signed_div
;
wire nforce_carry
=
nforce_carry_most | nsubtractb_idiv;
/********** NEW
The carry_in equation can be transformed into:
ci = ~(
~force_carry
& (~C | alu_invertbm | (~force_carry & ~with_carry))
& (C | ~alu_invertbm | (~force_carry & ~with_carry))
);
the terms:
inv_nfcwc = alu_invertbm | (~force_carry & ~with_carry)
notinv_nfcwc = ~alu_invertbm | (~force_carry & ~with_carry)
can be pipelined.
Thus allowing the final gate to be an OAI (which is fast)
**********/
wire ninv_nfcwc
= nalu_invertb | (~nforce_carry & ~nwith_carry);
wire nnotinv_nfcwc
= ~nalu_invertb | (~nforce_carry & ~nwith_carry);
wire ncarry_in_alu
=
(~alu_cc_carry | ninv_nfcwc)
& (alu_cc_carry | nnotinv_nfcwc)
;
wire ncarry_in_psr
=
(~ccm_lo_0 | ninv_nfcwc)
& (ccm_lo_0 | nnotinv_nfcwc)
;
wire ncarry_in_short
;
// Expanded macro begin.
// cmux2(carry_in_mux, 1, ncarry_in_short, ncarry_in_psr, ncarry_in_alu, setcc)
function [1:1] carry_in_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
carry_in_mux = out_fn ;
end
endfunction
assign ncarry_in_short = carry_in_mux( ncarry_in_psr, ncarry_in_alu, setcc) ;
// Expanded macro end.
wire ncarry_in
=
~(ncarry_in_short & ~nforce_carry)
;
wire carry_in;
Mflipflop_1 ycarry_in_reg_1(carry_in,ncarry_in,ss_clock,hold) ;
// ALU_TAGGED
wire nalu_tagged
=
d_hop3==`TADDCC | d_hop3==`TADDCCTV
| d_hop3==`TSUBCC | d_hop3==`TSUBCCTV;
wire alu_tagged
;
Mflipflop_1 alu_tag_ff_1( alu_tagged, nalu_tagged, ss_clock, hold) ;
// ALU_S2I_LSB2
// must not be inverted on tagged operations, even subtract
// so invert again if alu_invertbm is active
// note that alu_s2i_cnt comes directly out of reg, before
// the inverter, so don't need to invert it anymore.
wire [1:0] alu_s2i_lsb2
= alu_s2i_cnt[1:0]; // ^ {2{alu_invertbm}}
wire tagged_ovf =
alu_tagged
& (alu_s1s_lsb2[1] | alu_s1s_lsb2[0]
| alu_s2i_lsb2[1] | alu_s2i_lsb2[0])
;
// IMUL and IDIV control
// note that d_rs2 overlaps the low bits of the imm field
wire [1:0] src2m_imm_low2
=
// synopsys translate_off
(d_imm===1'bx) ? 'bx :
// synopsys translate_on
d_imm ? d_rs2_lo[1:0] : src2m_lo[1:0];
// this is the factor_sel used in the unpiped logic
assign factor_sel =
// synopsys translate_off
((ehop3_imulbasic & dopc_himul0_op)===1'bx) ? 'bx :
// synopsys translate_on
(ehop3_imulbasic & dopc_himul0_op)
? ({src2m_imm_low2[1:0],1'b0}) : alu_s2m_5_1[3:1]
;
// following are factor_sel used in pipelined logic
wire [2:0] first_factor_sel
= {src2m_imm_low2[1:0],1'b0};
wire [2:0] second_factor_sel
=
// synopsys translate_off
(d_imm===1'bx) ? 'bx :
// synopsys translate_on
d_imm ? d_rs2_lo[3:1] : src2m_lo[3:1];
wire [2:0] other_factor_sel
= alu_s2m_5_1[5:3];
wire pother_factor_sel2
;
Mflipflop_1 pofs2_reg_1(pother_factor_sel2,other_factor_sel[2],ss_clock,hold) ;
wire nrs1_clear_short
=
dhop3_imulbasic_op & (first_factor_sel == 3'b000
| first_factor_sel == 3'b111)
| dopc_himul0_op & (help_ctr == 6'b000000)
& (second_factor_sel == 3'b000
| second_factor_sel == 3'b111)
| dopc_himul0_op & ~(help_ctr == 6'b001111)
& ~(help_ctr == 6'b000000)
& (other_factor_sel == 3'b000
| other_factor_sel == 3'b111)
| dopc_himul0_op & (help_ctr == 6'b001111)
& ~(~signed_mult & pother_factor_sel2)
| dopc_himul1_op
| dopc_hidiv1_op & (help_ctr == 6'b000000)
& ndet_divovf
| dopc_hidiv2_op
;
wire nrs1_clear
= nrs1_clear_short & valid_decode;
wire rs1_clear_almost
;
Mflipflop_1 rs1_clear_almost_reg_1(rs1_clear_almost,nrs1_clear,ss_clock,hold) ;
wire rs1_clear_short
=
~ss_scan_mode &
(rs1_clear_almost
| dhop3_imulbasic_op
| dhop3_idivbasic_op)
;
wire rs1_clear =
rs1_clear_short & valid_decode_nilock & ~alus1_datam;
wire nrs1_double_short
=
dhop3_imulbasic_op & (first_factor_sel == 3'b001
| first_factor_sel == 3'b100)
| dopc_himul0_op & (help_ctr == 6'b000000)
& (second_factor_sel == 3'b011
| second_factor_sel == 3'b100)
| dopc_himul0_op & ~(help_ctr == 6'b000000)
& ~(help_ctr == 6'b001111)
& (other_factor_sel == 3'b011
| other_factor_sel == 3'b100)
;
wire nrs1_double
= nrs1_double_short & valid_decode;
wire rs1_double_alm
;
Mflipflop_1 rs1_double_reg_1(rs1_double_alm,nrs1_double,ss_clock,hold) ;
wire rs1_double = rs1_double_alm & ~alus1_datam;
wire rs1_pass = ~rs1_double & ~rs1_clear & ~alus1_datam;
// this term is here because we want to make sure no
// DP mux has all selects turned off. this will take
// the place of rs1_pass on one MUX in Mexec.
wire spc_mux_default = ~rs1_double & ~rs1_clear;
wire nrs1_negate_imul_short
=
dhop3_imulbasic_op & first_factor_sel[2]
| dopc_himul0_op & (help_ctr == 6'b000000)
& second_factor_sel[2]
| dopc_himul0_op & ~(help_ctr == 6'b000000)
& ~(help_ctr == 6'b001111)
& other_factor_sel[2]
;
wire nrs1_negate_idiv_short
=
dopc_hidiv1_op & (help_ctr == 6'b000000)
& ndet_divovf & ~(signed_div & ~nfinal_sgn)
;
wire nrs1_negate_imul
= nrs1_negate_imul_short & valid_decode;
wire nrs1_negate_idiv
= nrs1_negate_idiv_short & valid_decode;
wire rs1_negate_imul
;
wire rs1_negate_idiv
;
Mflipflop_1 rs1_negate_imul_reg_1(rs1_negate_imul,nrs1_negate_imul, ss_clock,hold) ;
Mflipflop_1 rs1_negate_idiv_reg_1(rs1_negate_idiv,nrs1_negate_idiv, ss_clock,hold) ;
wire nrs1_negate =
rs1_negate_imul & ~rs1_clear
| rs1_negate_idiv // & ~final_sgn
;
wire nrs1_negate_l = ~nrs1_negate;
// pipeline this too
wire next_e_not_negmul = ~ne_mulsm & ~nrs1_negate;
/*
* register in exec DP now
REGWIRE e_not_negmul;
REG(e_not_negmul_reg,1,e_not_negmul,next_e_not_negmul, ss_clock,hold)
*/
/*
* This portion of code has been modified to pipeline critical signals
*
REGWIRE pfactor_sel2;
REG(pfactor_sel_reg,1,pfactor_sel2,factor_sel[2],ss_clock,hold)
wire rs1_clear =
(
dhop3_imulbasic_op
| (dopc_himul0_op
& (factor_sel == 3'b0 | factor_sel == 3'b111))
| (~(~signed_mult & pfactor_sel2) & dopc_himul1_op)
| (dopc_himul2_op)
| dhop3_idivbasic_op
| dopc_hidiv3_op
)
;
wire rs1_double =
dopc_himul0_op
& (factor_sel == 3'b011 | factor_sel == 3'b100)
;
wire rs1_pass =
~rs1_clear & ~rs1_double
;
wire rs1_negate =
dopc_himul0_op & factor_sel[2] & ~rs1_clear
| dopc_hidiv3_op & det_divovf & ~final_sgn
;
*
*/
wire msign_bit =
// synopsys translate_off
(signed_mult===1'bx) ? 'bx :
// synopsys translate_on
signed_mult ? src1m_msb : 1'b0;
wire rs2_clear_short
=
(dhop3_imulbasic_op
| dopc_hidiv0_op & (help_ctr==6'b000000 | help_ctr==6'b000001)
| dopc_hidiv2_op
| dopc_hidiv3_op & det_divovf)
;
wire rs2_clear =
rs2_clear_short & valid_decode_nilock & ~alus2_datam;
// This signal is used to select the srl 2 MUX input for rs2
assign sel_srl2_mult =
(eopc_himul0 & dopc_himul0_op)
| dopc_himul1_op
;
// This signal is used to select the W reg output (registered
// alu_out) to mux directly into the ALU B input.
assign nsel_w_mult =
valid_decode
& (dopc_himul0_op | dopc_himul1_op)
;
// This signal controls the post-ALU shifter to Shift the multiply
// result 2 right
// wire sel_srl2_multalu =
// eopc_himul0;
// This signal is used to Shift in (1 left) the aluout into src1 reg
assign sel_rs1_shiftin =
dopc_hidiv2_op
| dopc_hidiv1_op & ~(help_ctr==6'b000000)
;
// This signal is used to select the shifted version of bypass
This page: |
Created: | Thu Aug 19 11:57:26 1999 |
| From: |
../../../sparc_v8/ssparc/iu/Mdecode/rtl/decode.v
|