input [1:0] select_fn ;
reg [ 1:1] out_fn ;
begin
case (select_fn) /* synopsys parallel_case */
2'b00: out_fn = in0_fn ;
2'b01: out_fn = in1_fn ;
2'b10: out_fn = in2_fn ;
2'b11: out_fn = in3_fn ;
default: out_fn = 65'hx;
endcase
wim_cwp_mux0 = out_fn ;
end
endfunction
assign wim_cwp0 = wim_cwp_mux0( wimm[0], wimm[1], wimm[2], wimm[3], real_cwp[1:0]) ;
// Expanded macro end.
wire wim_cwp1
;
// Expanded macro begin.
// cmux4(wim_cwp_mux1, 1, wim_cwp1, wimm[4], wimm[5], wimm[6], wimm[7], real_cwp[1:0])
function [ 1:1] wim_cwp_mux1 ;
input [ 1:1] in0_fn ;
input [ 1:1] in1_fn ;
input [ 1:1] in2_fn ;
input [ 1:1] in3_fn ;
input [1:0] select_fn ;
reg [ 1:1] out_fn ;
begin
case (select_fn) /* synopsys parallel_case */
2'b00: out_fn = in0_fn ;
2'b01: out_fn = in1_fn ;
2'b10: out_fn = in2_fn ;
2'b11: out_fn = in3_fn ;
default: out_fn = 65'hx;
endcase
wim_cwp_mux1 = out_fn ;
end
endfunction
assign wim_cwp1 = wim_cwp_mux1( wimm[4], wimm[5], wimm[6], wimm[7], real_cwp[1:0]) ;
// Expanded macro end.
wire wim_cwp
;
// Expanded macro begin.
// cmux2(wim_cwp_mux, 1, wim_cwp, wim_cwp0, wim_cwp1, real_cwp[2])
function [1:1] wim_cwp_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
wim_cwp_mux = out_fn ;
end
endfunction
assign wim_cwp = wim_cwp_mux(wim_cwp0, wim_cwp1, real_cwp[2]) ;
// Expanded macro end.
// wire wim_cwp; // used to be reg
// sLAVE(wim_cwp_slv,1, wim_cwp, wim_cwpm, ss_clock)
wire trape_wo_op
= e_hop3==`SAVE;
wire trape_wo = wim_cwp & trape_wo_op
& ~fold_annul;
wire trape_wu_op
= (e_hop3==`RESTORE | e_hop3==`RETT);
wire trape_wu = wim_cwp & trape_wu_op
& ~fold_annul;
// detect ADDRESS MISALIGNED in Execute
wire adr_bit0
= alu_out_lsb5[0];
wire adr_bit1
= alu_out_lsb5[1];
wire adr_bit2
= alu_out_lsb5[2];
wire msalgn_halfa
=
e_hop3==`LDSH | e_hop3==`LDSHA
| e_hop3==`LDUH | e_hop3==`LDUHA
| e_hop3==`STH | e_hop3==`STHA
;
wire msalgn_half
=
adr_bit0 & msalgn_halfa;
wire msalgn_worda
=
e_hop3==`LD | e_hop3==`LDA
| e_hop3==`LDF
| e_hop3==`LDFSR
| e_hop3==`SWAP | e_hop3==`SWAPA
| e_hop3==`ST | e_hop3==`STA
| e_hop3==`STF
| e_hop3==`STFSR
| e_hop3==`JMP | e_hop3==`RETT
;
wire msalgn_word
=
(adr_bit0 | adr_bit1) & msalgn_worda;
wire msalgn_dbla
=
e_hop3==`LDD | e_hop3==`LDDA
| e_hop3==`LDDF
| e_hop3==`STD | e_hop3==`STDA
| e_hop3==`STDF
| e_hop3==`STDFQ
;
wire msalgn_dbl
=
(adr_bit0 | adr_bit1 | adr_bit2) & msalgn_dbla;
wire trape_algn = (msalgn_half | msalgn_word | msalgn_dbl)
& ~fold_annul;
// detect TICC TRAP in Execute
wire trape_ticc_op
= e_hop3==`TICC & ~fold_annul;
/*
* New for SUNERGY Puma - pipeline bicc_taken (it is a D cycle
* signal in Puma, but E in Suntan) so the logic does not change
* for Puma.
*/
wire pbicc_taken
;
Mflipflop_1 pbicc_taken_reg_1( pbicc_taken, bicc_taken, ss_clock, hold) ;
wire trape_ticc = trape_ticc_op & pbicc_taken & ~fold_annul;
// detect DIVIDE BY 0 in execute
// note that the control logic receives alu_cc_zero inverted. must
// invert to correct it
wire alu_cc_zero_act
= ~alu_cc_zero;
wire trape_divz =
ehop3_idivbasic & alu_cc_zero_act & ~fold_annul;
// detect DATA ACCESS EXCEPTION trap in W
// all of these are now handled in the mtrap_control module
/*
This trap is actually detected in Result of a memory access
instruction, but because it is detected 1 cycle later than
all other traps, it is considered the highest priority trap
in the W cycle. Any other trap on the same memory access
instruction will be detected 1 cycle earlier, thus preventing
this trap.
* don't qualify W mem traps with data access inst in W. MMU is
* requesting this so that translations errors out of the store
* buffer can trap immediately even if there is no dacc in W. this
* simplifies the life of the MMU folks.
wire e_data_acc = ~fold_annul &
(e_hop==MEMALL | e_hop==HMEMALL);
REGWIRE w_data_acc;
REG(w_data_acc_reg,1,w_data_acc,e_data_acc,ss_clock,hold)
*
assign trapw_dae = mm_dacc_exc_w; // & w_data_acc
wire trapw_dmmum = mm_dacc_mmu_miss_w; // & w_data_acc
// DATA ACCESS ERROR TRAP in W
assign trapw_daer = mm_dacc_err_w; // & w_data_acc
*/
/* not for warthog
REG(r_dtacc_reg,1, r_data_acc, w_data_acc, ss_clock, hold)
assign trapr_dae = r_data_acc & mm_dacc_exc_r;
// detect DATA ACCESS MMU MISS EXCEPTION in RESULT
wire trapr_dmmum = r_data_acc & mm_dacc_mmu_miss_r;
// DATA ACCESS ERROR TRAP in R
assign trapr_daer = r_data_acc & mm_dacc_err_r;
*/
// wire in_merr; // used to be reg
// sLAVE(in_merr_slv,1, in_merr, MERRm, ss_clock)
// sLAVE(in_merr_slv,1, in_merr, 1'b0, ss_clock)
// check this - removed
// assign trapr_daer = (dt_perror
// | r_data_acc & in_merr
// );
// detect FLOATING POINT EXCEPTION trap in WRITE
// calculate in E and pipe to W
wire e_fpinstr_almost
=
e_hop2==`BFCC
| e_hop3[8:4]==`MEMF
| e_hop3==`FPOP | e_hop3==`FPCMP
;
wire e_fpinstr
= e_fpinstr_almost & ~TRAP & ~fold_annul;
wire w_fpi
;
Mflipflop_1 wfpi_ff_1( w_fpi, e_fpinstr, ss_clock, hold) ;
//grp dum grpTRAP1 out grpTRAP1 in grpTRAPCODE
wire trapw_fpe = w_fpi & fp_exc;
/*
* No R cycle FPexc detects in Puma/Martini
// detect FLOATING POINT EXCEPTION trap in RESULT
// Floating-point exceptions and co-processor exceptions can be
// detected in the R cycle only if FHOLD is active.
// This allows the FPU (CP) to freeze the pipe in the R cycle
// and then trap that instruction.
// calculate in W and pipe to R
//grp dum grpTRAP2 out grpTRAP2
wire w_fpinstr = ~TRAP & w_fpi
;
REG(fpinstr_ff,1, r_fpinstr, w_fpinstr, ss_clock, hold)
//grp out grpEREX
wire nen_rfexc = (FHOLD | trapr_fpe);
wire en_rfx_reg_sdin;
REG(en_rfx_reg,1, en_rfexc, nen_rfexc, ss_clock, 1'b0)
//grp dum grpTRAP1 out grpTRAP1 in grpTRAPCODE
assign trapr_fpe = r_fpinstr & en_rfexc & fp_exc;
*
*/
//grp dum grpTRAP1
// wire w_hophmemall = w_hop==HMEMALL;
// To allow data access exception to save the correct PC's
// if it is issued on the 2nd cycle of a load double or a store
// or a store double, WPC and TPC will be frozen whenever
// a help instruction of a memory access instr. is in the W stage.
// Also to allow the correct PC's to be trapped if MEXC is
// issued on the 2nd access cycle, the PC's must be frozen
// by the trap itself. Same situation for the floating-point
// and co-processor exceptions on FPOPS, CPOPS and the 2nd
// cycle of multicycle co-processor loads or stores.
// The d_trap term is necessary for the case in which the
// load or store takes some other trap in it's W cycle
// and also gets an MEXC.
//grp dum grpTRAP1 out grpTRAP1
// wire hld_wpctpc =
// ~ss_scan_mode & ~d_trap & ~reset &
// (w_hophmemall | trapr_dae);
// detect TAG-OVERFLOW trap in WRITE
//grp dum grpE1 out grpE1
wire e_tagcctv
= ~fold_annul & (
e_hop3==`TADDCCTV | e_hop3==`TSUBCCTV);
wire w_tagcctv
;
Mflipflop_1 w_tagcctv_reg_1( w_tagcctv, e_tagcctv, ss_clock, hold) ;
//grp dum grpTRAP1 out grpTRAP1 in grpTRAPCODE
wire trapw_tag =
ccm_V & w_tagcctv;
// detect INTERRUPT in WRITE
/*
Interrupts are masked in software with the ET bit of the PSR
and by the Processor Interrupt Level (PIL). They are also masked
with hardware in certain stages of the pipeline (no_interrupts).
This hardware mask is generally applied where the PC's will be
incorrect for a trap, such as during help instructions or during
interlocks.
*/
/*
Don't allow an annuled delay slot of a folded branch
to take an interrupt. ditto for help cycles.
*/
wire e_no_ints_l
= ~(e_help | fold_annul);
wire no_interrupts_l
;
Mflipflop_1 no_ints_ff_1( no_interrupts_l, e_no_ints_l, ss_clock, hold) ;
/*
* Because of a bug in the MMU, there is a change in the IU
* to work around it. The nature of the bug was to insert
* a register between the IRL/PIL comparison and the trap
* prioritizer. Unfortunately, this can cause a situation
* where the interrupt taken has a lower priority than value
* in the PIL (in the event of back to back wrpsr's).
*
* To fix this problem, the IU now disables the interrupt request
* when it detects a wrpsr in the R cycle. Do this by turning
* the IRL lines off.
*
*/
wire r_wrpsr
;
Mflipflop_1 r_wrpsr_reg_1(r_wrpsr,w_wrpsr,ss_clock,hold) ;
// note that int_req_lev is an active low signal.
// right now, it is not, so i will invert it here.
wire [3:0] int_req_lev_l
= ~(int_req_lev & ~{4{w_wrpsr|r_wrpsr}});
Mtrapw_int trapw_int_mod (trapw_int, pil, int_req_lev_l, et, no_interrupts_l,hold, ss_clock);
/*
* removed and replaced by equivalent module (Mtrapw_int) to
* improve synopsys' ability to speed it up
//The following new solution is based on the observation that the carry-out
//of (int_req_lev[3:0] + ~pil[3:0]) is int_req_lev > pil. This carry
//out (C3) is:
//
// C3 = G3 | G2 & P3 | G1 & P2 & P3 | G0 & P1 & P2 & P3
//
//where the P terms and G terms are the propagate and generate (OR and AND)
//for each bit pair.
//
//to handle the non-maskable case, an additional term:
//
// (int_req_lev[3] & int_req_lev[2] & int_req_lev[1] & int_req_lev[0])
//
//is ored in. Implementation consists of 3 AND gates to compute the P terms
//(inverted) and 5 NOR gates to compute each product term followed by a
//wire-or of the 5 product terms.
wire [3:0] irl_ = ~int_req_lev;
// carry propagate terms for int_req_lev + ~irl
wire p1_ = irl_[1] & pil[1];
wire p2_ = irl_[2] & pil[2];
wire p3_ = irl_[3] & pil[3];
wire irq =(
(~(p1_ | p2_ | p3_ | pil[0] | irl_[0])) // NOR5C_HW
| (~( p2_ | p3_ | pil[1] | irl_[1])) // NOR4C_HW
| (~( p3_ | pil[2] | irl_[2])) // NOR3C_HW
| (~( pil[3] | irl_[3])) // NOR2C_HW
| (~(irl_[0] | irl_[1] | irl_[2] | irl_[3])) // NOR4C_HW
)
;
//endif
assign trapw_int = et & ~no_interrupts & irq;
*/
endmodule
module Mfp_control
(
e_hop3,
w_hop3,
select_FP_DOUT,
sel_ldstb_1,
select_IU_DOUT
);
// input ANNUL;
// input [8:0] d_hop3;
// input d_nop;
// input d_trap;
input [8:0] e_hop3
;
input [8:0] w_hop3
;
//output dop_finst;
output select_FP_DOUT
;
output sel_ldstb_1
;
output select_IU_DOUT
;
// Mux control to select between FP and IU data
wire select_FP_DOUT =
e_hop3==`STF | e_hop3==`STDF
| e_hop3==`STFSR
| e_hop3==`STDFQ
;
wire sel_ldstb_1 =
e_hop3==`LDSTB | e_hop3==`LDSTBA
| w_hop3==`LDSTB | w_hop3==`LDSTBA;
wire select_IU_DOUT = ~select_FP_DOUT & ~sel_ldstb_1;
// FPU and CP INSTRUCTION DECODING
// full decodes are necessary below to prevent transmission of
// an illegal opcode to the FPU or co-processor
// wire dop_finst =
// (d_hop3==FPOP | d_hop3==FPCMP
// | d_hop3==LDF | d_hop3==LDDF | d_hop3==LDFSR
// | d_hop3==STF | d_hop3==STDF | d_hop3==STFSR | d_hop3==STDFQ
// )
// & ~d_nop & ~d_trap & ~ANNUL
// ;
endmodule
module Mir_control
(
TRAP,
ss_clock,
d_op,
d_op3,
d_rd_basic,
hnop_into_ex,
hold,
htrap_into_ex,
next_d_hhn,
valid_decode,
gen_help,
interlock,
valid_decode_nilock,
// synopsys translate_off
w_op,
w_op3,
// synopsys translate_on
d_rd_hstd_sel,
d_rd,
word_store_d,
half_store_d,
byte_store_d,
clear_rd0m,
d_hhn,
e_hhn,
set_rd0m,
w_hhn,
hld_dirreg,
hld_dirreg_rf
);
input TRAP
;
input ss_clock
;
input [1:0] d_op
;
input [5:0] d_op3
;
input [4:0] d_rd_basic
;
input hnop_into_ex
;
input hold
;
input htrap_into_ex
;
input [2:0] next_d_hhn
;
input valid_decode
;
input gen_help
;
input interlock
;
input valid_decode_nilock
;
// synopsys translate_off
input [1:0] w_op
;
input [5:0] w_op3
;
// synopsys translate_on
output d_rd_hstd_sel
;
output [4:0] d_rd
;
output word_store_d
;
output half_store_d
;
output byte_store_d
;
output clear_rd0m
;
output [2:0] d_hhn
;
output [2:0] e_hhn
;
output set_rd0m
;
output [2:0] w_hhn
;
output hld_dirreg
;
output hld_dirreg_rf
;
// HELP OPCODE PIPELINE
// DECODE
wire [2:0] d_hhn; // decode stage help + help number
Mflipflop_3 d_hhn_reg_3( d_hhn, next_d_hhn, ss_clock, hold) ;
// synopsys translate_off
wire d_hhn2_dummy
;
Mflipflop_1 d_hhn2_dummy_reg_1(d_hhn2_dummy,next_d_hhn[2],ss_clock,hold) ;
// synopsys translate_on
// MUX for inserting HTRAP and HNOP into execute
wire hnoptrap_into_ex
= hnop_into_ex | htrap_into_ex;
wire [2:0] d_hhn_mux
;
// Expanded macro begin.
// cmux2(hhn_mux_d, 3, d_hhn_mux, d_hhn, 4, hnoptrap_into_ex)
function [ 3:1] hhn_mux_d ;
input [ 3:1] in0_fn ;
input [ 3:1] in1_fn ;
input select_fn ;
reg [ 3: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
hhn_mux_d = out_fn ;
end
endfunction
assign d_hhn_mux = hhn_mux_d( d_hhn, 4, hnoptrap_into_ex) ;
// Expanded macro end.
// EXECUTE
wire [2:0] e_hhn;
Mflipflop_3 e_hhn_master_3( e_hhn, d_hhn_mux, ss_clock, hold) ;
// MUX for inserting HNOP into write
wire [2:0] e_hhn_mux
;
// Expanded macro begin.
// cmux2(e_hhn_mux_mux, 3, e_hhn_mux, e_hhn, 4, TRAP)
function [ 3:1] e_hhn_mux_mux ;
input [ 3:1] in0_fn ;
input [ 3:1] in1_fn ;
input select_fn ;
reg [ 3: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
e_hhn_mux_mux = out_fn ;
end
endfunction
assign e_hhn_mux = e_hhn_mux_mux( e_hhn, 4, TRAP) ;
// Expanded macro end.
// WRITE
wire [2:0] w_hhn;
Mflipflop_3 w_hhn_reg_3( w_hhn, e_hhn_mux, ss_clock, hold) ;
// MUX for inserting HNOP into result
/* synopsys translate_off */
wire [2:0] w_hhn_mux
;
// Expanded macro begin.
// cmux2(w_hhn_mux, 3, w_hhn_mux, w_hhn, 4, TRAP)
function [ 3:1] hhn_mux ;
input [ 3:1] in0_fn ;
input [ 3:1] in1_fn ;
input select_fn ;
reg [ 3: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
hhn_mux = out_fn ;
end
endfunction
assign w_hhn_mux = hhn_mux( w_hhn, 4, TRAP) ;
// Expanded macro end.
/* synopsys translate_on */
// RESULT
/* synopsys translate_off */
wire [2:0] r_hhn
;
Mflipflop_3 r_hhn_reg_3( r_hhn, w_hhn_mux, ss_clock, hold) ;
/* synopsys translate_on */
// OPCODE FIELDS OF THE INSTRUCTION IN DECODE
wire [10:0] d_opcode
= {d_hhn[2], d_op, d_op3, d_hhn[1:0]};
// complete opcode
// wire d_help = d_opcode[10]; // help bit
// wire [2:0] d_hop = d_opcode[10:8]; // h + op
// wire [5:0] d_hop2 = d_opcode[10:5]; // h + op + op2
wire [8:0] d_hop3
= d_opcode[10:2]; // h + op + op3
// OPCODE FIELDS OF THE INSTRUCTION IN EXECUTE
/*
* See after the instanciation of Mir_control for this
assign e_opcode = {e_hhn[2], e_op, e_op3, e_hhn[1:0]};
// complete opcode
wire e_help = e_opcode[10]; // help bit
assign e_hop = e_opcode[10:8]; // h + op
assign e_hop2 = e_opcode[10:5]; // h + op + op2
assign e_hop3 = e_opcode[10:2]; // h + op + op3
*
*/
// OPCODE FIELDS OF THE INSTRUCTION IN WRITE
// complete opcode
// synopsys translate_off
wire [10:0] w_opcode
= {w_hhn[2], w_op, w_op3, w_hhn[1:0]};
wire w_help
= w_opcode[10]; // help bit
wire [5:0] w_hop2
= w_opcode[10:5]; // h + op + op2
// synopsys translate_on
// wire [2:0] w_hop = w_opcode[10:8]; // h + op
// wire [8:0] w_hop3 = w_opcode[10:2]; // h + op + op3
// OPCODE FIELDS OF THE INSTRUCTION IN RESULT
//grp in grpR1
// synopsys translate_off
wire [10:0] r_opcode
;
wire [1:0] r_op
= `IU.iuchip.decode.ir.r_op;
wire [5:0] r_op3
= `IU.iuchip.decode.ir.r_op3;
assign r_opcode = {r_hhn[2], r_op, r_op3, r_hhn[1:0]};
// complete opcode
wire r_help
= r_opcode[10]; // help bit
// synopsys translate_on
// wire [2:0] r_hop = r_opcode[10:8]; // h + op
// wire [5:0] r_hop2 = r_opcode[10:5]; // h + op + op2
// wire [8:0] r_hop3 = r_opcode[10:2]; // h + op + op3
// temporary STORE ALIGNER controls
wire half_store_d =
d_hop3==`STH | d_hop3==`STHA
;
wire byte_store_d =
d_hop3==`STB | d_hop3==`STBA
;
wire word_store_d = ~half_store_d & ~byte_store_d;
wire d_rd_hstd_sel =
d_opcode==`HSTD0 | d_opcode==`HSTDA0;
wire [4:0] d_rd;
wire [4:0] d_rd_inc
= ({d_rd_basic[4:1],1'b1});
// Expanded macro begin.
// cmux2(d_rd_mux, 5, d_rd, d_rd_basic, d_rd_inc, d_rd_hstd_sel)
function [5:1] d_rd_mux ;
input [5:1] in0_fn ;
input [5:1] in1_fn ;
input select_fn ;
reg [5: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
d_rd_mux = out_fn ;
end
endfunction
assign d_rd = d_rd_mux(d_rd_basic, d_rd_inc, d_rd_hstd_sel) ;
// Expanded macro end.
// LDD / STD RD LSB CONTROL
/*
For integer load double and store double
the least significant bit of the Rd register
specifier must be controllable. For the 1st
word of LDD or STD, the lsb must be 0, and for the second
word it must be 1
*/
wire clear_rd0m = valid_decode &
(d_hop3==`LDD | d_hop3==`LDDA
| d_hop3==`STD | d_hop3==`STDA)
;
wire set_rd0m = valid_decode &
(d_opcode==`HLDD | d_opcode==`HLDDA)
// | d_opcode==HSTD0 | d_opcode==HSTDA0)
;
// Use the hld_dirreg signal to hold the dir register. Note
// that there is a similar signal hld_dir. This will have to
// be fixed. hld_dirreg and hld_dir are also used to hold
// the mm_iacc_exc_d register. see also hld_drs1_reg
wire hld_dirreg =
gen_help
| valid_decode_nilock & interlock
;
// | ~load_dir & ic_sustain_imhold
// hold // & ~(load_dir & null_in_d)
wire hld_dirreg_rf =
gen_help | hold
| valid_decode_nilock & interlock
;
endmodule
module Mpc_control
(
TRAP,
ss_clock,
d_hop,
d_nop,
d_trap,
e_hop3,
fcc_ilock,
hold,
interlock,
// jmp_ilock,
nERROR,
nreset,
reset,
ss_scan_mode,
valid_decode,
e_call,
e_jmprett,
hld_dpc,
hld_dum_dpc,
sadr_jmprett,
sadr_tbr,
sadr_zero
);
input TRAP
;
input ss_clock
;
input [2:0] d_hop
;
input d_nop
;
input d_trap
;
input [8:0] e_hop3
;
input fcc_ilock
;
input hold
;
input interlock
;
//input jmp_ilock;
input nERROR
;
input nreset
;
input reset
;
input ss_scan_mode
;
input valid_decode
;
output e_call
;
output e_jmprett
;
output hld_dpc
;
output hld_dum_dpc
;
output sadr_jmprett
;
output sadr_tbr
;
output sadr_zero
;
//FORWARD DEC
wire d_bcop
;
wire e_call;
// wire [2:0] d_hop = d_hop3[8:6];
// wire [8:0] e_hop3 = e_opcode[10:2];
/**********************************************************************
*
* Modified extensively for SUNERGY
*
*/
/*
* New for SUNERGY - next address selects
*/
// Use ALU output for JMP/RETT instruction addresses
// also use the alu output for IFLUSH addresses
wire sadr_jmprett =
~reset & ~ss_scan_mode
& (e_hop3==`JMP | e_hop3==`RETT) // | e_opcode==HIFLUSH0)
;
// wire aas1_branch = ~d_op30m;
/* See after Mpc_control instanciation for aas1_call
wire aas1_call = d_op30m;
*/
// Use Address Adder output for all branch and call
/* sadr_aa is part of the critical path so we need to speed it up.
following logic is too slow - move bicc_taken out
*/
/*
* used to have this term to prevent addr going out when a bi/fcc
* or call was in D. now, addr goes out, but queue control prevents
* fetched data from being loaded into the queue.
& ~no_imid_ilock
*/
/* move to pc_cntl
wire saa_null =
~reset & ~ANNUL
& ~d_nop & ~d_trap
;
wire sadr_aa_callbfcc =
(
(d_hop2bfccc & ~fcc_ilock) // & bcop_taken)
| d_hop == CALL
) & saa_null
;
wire sadr_aa_bicc_almost =
d_hop2bicc & saa_null;
wire sadr_aa = ~ss_scan_mode & ~iacc_exc_mmumiss_d & (
sadr_aa_callbfcc
| sadr_aa_bicc_almost
);
*/
// SADR_TBR select next address from TBR
wire nsadr_tbr
= TRAP & ~nERROR & ~nreset;
wire sadr_tbr_almost
;
Mflipflop_1 trap_adr_reg_1( sadr_tbr_almost, nsadr_tbr, ss_clock, hold) ;
wire sadr_tbr = sadr_tbr_almost & ~ss_scan_mode;
// SADR_ZERO select address = 0 for I fetch
wire nsadr_zero
= nERROR | nreset;
wire sadr_zero;
Mflipflop_1 sadr_zero_reg_1(sadr_zero,nsadr_zero,ss_clock,hold) ;
/*
* not needed
wire sadr_inc = ~sadr_tbr & ~ss_scan_mode & ~reset &
~sadr_jmprett & ~sadr_aa
;
*/
/*
* End new for SUNERGY
*/
// CTL_XFR
/* Do we need this for SUNERGY Puma - */
// determine when a control transfer target is being fetched
//grp dum grpD0 out grpD0 in grpNIB
wire d_hopcall
= d_hop==`CALL;
//grp dum grpNIB out grpNIB
wire d_call
= valid_decode & d_hopcall;
Mflipflop_1 e_call_reg_1(e_call, d_call, ss_clock, hold) ;
assign e_jmprett = e_hop3==`JMP | e_hop3==`RETT;
//---------------------------------------------------------------------------
// NEXT ADDRESS MUX ZERO
// full qualification of branch instructions with valid_decode
// is impossible for timing reasons. The partial qualification allows
// interlocked branches or annulled branches to generate
// their target addresses. These are then treated like
// an untaken branch, and the pc recovered from PC_BUF
// wire d_branch = ~d_nop & ~mm_iacc_exc_d & ~d_trap &
// (d_hop2==BICC | d_hop2==BFCC | d_hop==CALL);
// SADR_ZERO
// New ADDRESS INCREMENTER CONTROLS for SUNERGY
// NEXT DPC CONTROL
// hold DPC
// d_nop indicates instruction starvation.
// Do not hold DPC in (d_trap) trap_cyc2 in any case
// because it must be loaded with the trap handler address.
// always hold the DPC during interlocks (instr. will be repeated)
// and on help opcodes (PC has been advanced to the next instr.).
// interlock is forced low on d_trap and reset.
// now hold DPC during scan mode - it is no longer scanned
// (sunergy note - it is scanned)
//grp dum grpD2 out grpD2 in grpD3cout
// assign hld_dpc =
// ss_scan_mode | (interlock | (~reset & ~d_trap &
// (d_nop | d_help )));
/*
* For SUNERGY, don't hold dpc on help inst
*/
// used to have scan_mode in it
assign hld_dpc =
interlock | (~reset & ~d_trap & d_nop);
wire hld_dum_dpc = hld_dpc; // | hold
// next DPC from address register
// now must qualify with ~hld_dpc since these are
// independent mux selects
// this signal is used to bypass the I$address going out from
// from a jmp instruction directly to the DPC in the event
// that the jmp's delay slot had a parity error. this makes
// sure that the pc's saved because of the trap are correct.
// they can be incorrect because of problems with sadr_inc0's
// determination - it has a special dhop3=jmp term that
// really screws things up in this case.
// wire cheat_pcfwd = jmp_ilock & iacc_exc_mmumiss_d;
endmodule
module Mdcache_control
(
alu_out_lsb2,
d_asi,
d_opcode,
fold_annul,
nalternate_e,
reset,
valid_decode,
hold,
ss_clock,
TRAP,
byte_mark0_e,
byte_mark1_e,
byte_mark2_e,
byte_mark3_e,
ld_op_e,
ld_op_e_mmu,
ld_op_d,
sgnd_ld_e,
st_op_e,
st_op_e_mmu,
st_op_d,
fpu_mem_e,
iu_iflush_e,
size_e
);
input [1:0] alu_out_lsb2
;
input [5:4] d_asi
;
input [10:0] d_opcode
;
input fold_annul
;
input nalternate_e
;
input reset
;
input valid_decode
;
input hold
;
input ss_clock
;
input TRAP
;
output byte_mark0_e
;
output byte_mark1_e
;
output byte_mark2_e
;
output byte_mark3_e
;
output ld_op_e
;
output ld_op_e_mmu
;
output ld_op_d
;
output sgnd_ld_e
;
output st_op_e
;
output st_op_e_mmu
;
output st_op_d
;
//output flush_ic_e;
This page: |
Created: | Thu Aug 19 11:57:30 1999 |
| From: |
../../../sparc_v8/ssparc/iu/Mdecode/rtl/decode.v
|