/******************************************************************************/
/* */
/* Copyright (c) 1999 Sun Microsystems, Inc. All rights reserved. */
/* */
/* The contents of this file are subject to the current version of the Sun */
/* Community Source License, microSPARCII ("the License"). You may not use */
/* this file except in compliance with the License. You may obtain a copy */
/* of the License by searching for "Sun Community Source License" on the */
/* World Wide Web at http://www.sun.com. See the License for the rights, */
/* obligations, and limitations governing use of the contents of this file. */
/* */
/* Sun Microsystems, Inc. has intellectual property rights relating to the */
/* technology embodied in these files. In particular, and without limitation, */
/* these intellectual property rights may include one or more U.S. patents, */
/* foreign patents, or pending applications. */
/* */
/* Sun, Sun Microsystems, the Sun logo, all Sun-based trademarks and logos, */
/* Solaris, Java and all Java-based trademarks and logos are trademarks or */
/* registered trademarks of Sun Microsystems, Inc. in the United States and */
/* other countries. microSPARC is a trademark or registered trademark of */
/* SPARC International, Inc. All SPARC trademarks are used under license and */
/* are trademarks or registered trademarks of SPARC International, Inc. in */
/* the United States and other countries. Products bearing SPARC trademarks */
/* are based upon an architecture developed by Sun Microsystems, Inc. */
/* */
/******************************************************************************/
/***************************************************************************
****************************************************************************
***
*** Program File: @(#)exec.v
***
****************************************************************************
****************************************************************************/
// @(#)exec.v 1.42 3/18/93
// exec.v
/*
This file describes the data-path of suntan for the execute
stage of the pipeline. It includes the ALU source muxes,
ALU input latches, ALU proper, barrel shifter, condition-code
generation, condition code register, and the ALU output register.
*/
module Mexec
( alu_out_lsb5, alu_s1m_0, alu_s2m_5_0,
alu_shift, alu_shift_dc,
high_2_1,
result, alu_cc_next, alu_s1s_lsb2,
src1m,
disp22, src2m,
tpc, wpc, wimm, ym_lo3, tbrm,
e_rdpsrm, e_rdwimm, e_rdym, e_rdtbrm, e_jmpcallm, rdtpcm,
alus1_datam, alus1_rfm_b3m, alus1_b2m,
alus1_b1m, alus1_setm,
alus2_datam, a2top_default, rs2_passit,
d_imm, d_imm_l,
alus2_b2m,
alus2_b1m,
alu_s2_reg_hold,
carry_in, pass_hi_rs1,
det_divovf,
alu_ADD, alu_AND, alu_XNOR,
tagged_ovf, alu_sub,
shift_left, arith_shift,
rs_from_sh, rs_from_alu, rs_from_else,
force_neg, force_pos,
rs1_pass, spc_mux_default,
rs1_clear, rs1_double, nrs1_negate, nrs1_negate_l,
sel_srl2_mult, rs2_clear, nsel_w_mult, nsel_w_mult_l_b,
nsel_w_mult_l_not_b,
sel_sll1_divalu, sel_sll1_divalu_l,
msign_bit, dsign_bit1, dsign_bit2, rf2_imm_data_msb,
hold_Wreg,
idiv_shiftin_low,
eopc_hidiv3,
use_hi_y, use_hi_alu, use_hi_rs1_default,
use_hi_rs2, use_low_rs1, use_hi_rs2_default, not_rs2_rs1_default,
alus1_b2_shift, sel_rs1_shiftin,
ne_mulsm, next_e_not_negmul,
sel_pcspec_l,
ss_clock,
hold_Mexec1, hold_Mexec2,hold_Mexec3, ss_scan_mode,
hld_wim,
trapcode, TRAP, hld_tba, hld_tt, n_hld_tt_scan,
n_ymsb, wr_y, wr_mulscc, hld_y,
cwp, cwpm_, ncwpm_, ecwpm_, wcwpm1, cwpp1, cwpm1, wcwp, ccm,
s, little_endian, sm, ns, psm, et, ef, pil,
hold_cc, load_cc, write_cc, restore_cc,
clret_sets, setet_ps2s, write_etps, hold_ets,
s_into_ps, hold_ps,
hld_pilefec,
w_wrpsr,
cwp_inc, cwp_dec, cwp_hold, ecwp_next,
cwp_recirc,
ld_iu,
ccN_noninv,
ccZ_noninv,
exec_scan_in,
exec_scan_out
);
// OUTPUTS
output [4:0] alu_out_lsb5
; // 5 lsb's used for alignment check
output alu_s1m_0
; // LSB of alu_s1m
output [5:0] alu_s2m_5_0
; // alu source 2 mux output (to adder)
output [31:0] alu_shift
; // ditto.
output [31:0] alu_shift_dc
; // dedicated iu_dva_e for D$
// output [1:0] which_byte_; // used for load align
output [31:0] result
; // result register
//output [6:0] result_lo; // result register
output high_2_1
; // sgn bit of 34 bit adds
output [3:0] alu_cc_next
; // new cc's from ALU
output ccN_noninv
; // noninverted output to decode/icceval
output ccZ_noninv
; // noninverted output to decode/icceval
output [1:0] alu_s1s_lsb2
; // lsb of alu_s1 to decode.v for tagged
// INPUTS
input [31:0] src1m
; // regfile read port 1 output
input [21:0] disp22
; // least significant 22 bits of in_exm
input [31:0] src2m
; // regfile read port2 output
input [31:2] tpc
; // Trap PC master
input [31:2] wpc
; // Write PC
output [7:0] wimm
; // WIM
output [2:0] ym_lo3
; // Y register master
output [31:4] tbrm
; // TBR
// CONTROLS
input e_rdpsrm
; // Ex RDPSR
input e_rdwimm
; // Ex RDWIM
input e_rdym
; // Ex RDY
input e_rdtbrm
; // Ex RDTBR
input e_jmpcallm
; // Ex JMP or CALL
input rdtpcm
; // TRAP or trap_cyc1
input alus1_datam
; // alu source 1 from load data
input alus1_rfm_b3m
; // alu source 1 from register file
//input alus1_b3m; // alu source 1 from bypass 3
input alus1_b2m
; // alu source 1 from bypass 2
input alus1_b1m
; // alu source 1 from bypass 1
input alus1_setm
; // alu source 1 from sethi data
input alus2_datam
; // alu source 2 from load data
//input alus2_rfm_im_b3m; // alu source 2 from register file
input a2top_default
;
input rs2_passit
;
input d_imm
;
input d_imm_l
;
input alus2_b2m
; // alu source 2 from bypass 2
input alus2_b1m
; // alu source 2 from bypass 1
//input alus2_b3m; // alu source 2 from bypass 3
input alu_s2_reg_hold
; // hold alu src 2 register
input carry_in
; // ALU carry in
input pass_hi_rs1
; // pass high bit of src1 to alu
// was clr_hi_rs1
input det_divovf
; // idiv overflow
input alu_ADD
; // alu add control
input alu_AND
; // alu and control
input alu_XNOR
; // alu xor control
input tagged_ovf
; // alu is doing a tagged add
input alu_sub
; // alu is doing a subtract (invert C)
//input [4:0] shift_cnt; // amount to Shift by
input shift_left
; // Shift left (=0 for right)
input arith_shift
; // arith Shift (=1 for logical)
input rs_from_sh
; // select shifter result or align
input rs_from_alu
; // select ALU result
input rs_from_else
; // select result from special mux
input force_neg
; // for signed (neg) idiv ovf
input force_pos
; // for signed (pos) idiv ovf
input rs1_pass
; // pass RF src1 to register
input spc_mux_default
; // ditto - different mux
input rs1_clear
; // clear RF src1 to register
input rs1_double
; // sll 1 RF src1 to register
input nrs1_negate
; // negate RF src1 to register
input nrs1_negate_l
; // negate RF src1 to reg (active low)
input sel_srl2_mult
; // select srl2 result to register
input rs2_clear
; // clear RF src2 to register
input nsel_w_mult
; // select W result to alu
input nsel_w_mult_l_b
; // not select W result to alu and b
input nsel_w_mult_l_not_b
; // not select W result to alu and inv b
input sel_sll1_divalu
; // Shift alu result 1 left WITH W
input sel_sll1_divalu_l
; // not Shift alu result 1 left WITH W
input msign_bit
; // op in D is signed mult
input dsign_bit1
; //
input dsign_bit2
; //
output rf2_imm_data_msb
; // most sig. bit of rf2_imm_data
input hold_Wreg
; // hold result register
input idiv_shiftin_low
; // final sign of idiv xnor high_2_1
input eopc_hidiv3
; // HIDIV3 is in E
input use_hi_y
; // use y for sgn ext bit[33:32] alu src1 -idiv
input use_hi_alu
; // use alu output - idiv
input use_hi_rs1_default
; // use default - idiv
input use_hi_rs2
; // use RF B for sgn ext bit[33:32] alu src2-id
input use_low_rs1
; // use low bit of src1 register - idiv
input use_hi_rs2_default
; // use default - idiv
input not_rs2_rs1_default
; //not the above 3 select
input alus1_b2_shift
; // idiv corr step - Shift bypasss2 select
input sel_rs1_shiftin
; // idiv loop step - Shift aluout select
input ne_mulsm
; // Shift src1 in for multiply step
input next_e_not_negmul
; // not a mulscc or negate (rs1)
input sel_pcspec_l
; // not selecting pc or special reg.
input hld_wim
; // reset input
// I/O for tbr_mod
input [7:0] trapcode
; // encoded trap type
input TRAP
; // contrl to write TT
input hld_tba
; // tbr hold control
input hld_tt
; // TT hold control
input n_hld_tt_scan
; // not TT hold and not scan_mode
input n_ymsb
; // next Y msb for Shifts
input wr_y
; // write result into y.
input wr_mulscc
; // write mulscc into y
input hld_y
; // clock hold for Y register
// I/O for psr_mod
output [2:0] cwp
; // Current Window Pointer
output [2:0] cwpm_
; // Current Window Pointer master (active low)
output [2:0] ncwpm_
;
output [2:0] ecwpm_
; // Previous cwp master (used for rd xlate) (active low)
input [2:0] wcwpm1
; // w cwp master -1
input [2:0] cwpp1
; // cwp master + 1
input [2:0] cwpm1
; // cwp master - 1
output [2:0] wcwp
; //
output [3:0] ccm
; // Condition Codes Master latched
output s
; // supervisor bit
output sm
; // same, just a copy for the MMU
output little_endian
; // add for little_endian control
output ns
; // next supervisor bit in wrpsr
output psm
; // previous supervisor bit master version
output et
; // trap enable bit
output ef
; // enable FPU
output [3:0] pil
; // Processor Interrupt Level
input hold_cc
; // hold CC's
input load_cc
; // load CC's from ALU
input write_cc
; // write CC's from result (wrpsr)
input restore_cc
; // restore CC's due to trap on setcc instr.
input clret_sets
; // clear ET and set S
input setet_ps2s
; // set ET
input write_etps
; // load ET (wrpsr)
input hold_ets
; // hold ET
input s_into_ps
; // PS controls
input hold_ps
;
input hld_pilefec
; // hold control for PIL, EF, and EC
input w_wrpsr
; // W cycle of WRPSR
input cwp_inc
; // increment cwp
input cwp_dec
; // decrement cwp
input cwp_hold
; // hold cwp
input ecwp_next
; // normal cwp pipe advance
input cwp_recirc
;
// I/O for din.v
// output [31:0] rfwrdata; // register file write data (master timing)
// output [31:0] algnd_datm;
input [31:0] ld_iu
; // the input Data bus
//output [63:0] iu_dout; // IU data output to D$
//input [31:0] src3; // store data from RF (bypass in rf, too)
//input [63:0] fp_dout; // FP store data
//input select_FP_DOUT; // used to select FP data at mux
//input sel_ldstb_1; // used to select ldstb (-1) at mux
//input select_IU_DOUT; // used to select IU data at mux
/*input m3b3; // select for mux3 from byte 3
input m3b2; // select for mux3 from byte 2
input m3b1; // select for mux3 from byte 1
input m3b0; // select for mux3 from byte 0
input m20; // select for mux2 from 0
input m2b2; // select for mux2 from byte 2
input m2b0; // select for mux2 from byte 0
input m2s0; // select for mux2 from sign 0
input m2s2; // select for mux2 from sign 2
input m0m10; // select for mux0 & 1 from 2
input m0m1b0b1; // select for mux0 & 1 from byte 0 byte 1
input m0m1s0; // select for mux0 & 1 from sign 0
input m0m1s2; // select for mux0 & 1 from sign 2
input m0m1m2s1; // select for mux0 & 1 & 2 from sign 1
input m0m1m2s3; // select for mux0 & 1 & 2 from sign 3
input wr_lddatam_l; // select for write from result
//input almost_rf_we; // use to clock gate to make rf_we
//output rf_we; // reg file we
input dc_ldd_stb_l; // strobe ldd register
input dc_sel_ldd_reg; // select ldd register for 2nd word of LDD
*/
// MISC
input ss_clock
; // main clock
input hold_Mexec1
; // main hold
input hold_Mexec2
; // main hold
input hold_Mexec3
; // main hold
input ss_scan_mode
;
input exec_scan_in
;
output exec_scan_out
;
// FORWARD DECLARATIONS
wire [31:0] result;
// wire result_MSB = result[31];
// wire [6:0] result_lo = result[6:0];
wire ns = result[7];
wire [31:0] alu_s2m
;
wire [5:0] alu_s2m_5_0 = alu_s2m[5:0];
reg [31:0] wrdatam
; // write master. Needed for bypass 2
wire [31:0] alu_shift;
wire [31:0] alu_shift_dc;
wire [31:0] dcar_inc
;
// wire [31:0] algnd_datm;
wire [31:0] d_car
;
wire [31:0] d_mar
;
wire [31:0] W_alushift_out
;
wire [1:0] high_2
;
wire [1:0] result_high2
;
wire [0:3] car_byte_marks
;
wire [0:3] mar_byte_marks
;
wire [3:0] ccm;
wire cc_next3
;
wire cc_next1
;
/*
* removed - ldalign is part of D$ now
Mdin din (algnd_datm,
ld_iu, result, dc_ldd_stb_l, dc_sel_ldd_reg,
m3b3, m3b2, m3b1, m3b0, m20, m2b2, m2b0, m2s0, m2s2,
m0m10, m0m1b0b1, m0m1s0, m0m1s2, m0m1m2s1, m0m1m2s3,
wr_lddatam_l, ss_clock
);
*/
/*
* some registered controls from Mdecode
*/
wire e_mulsm
;
Mflipflop_1 e_mulsm_reg_1(e_mulsm,ne_mulsm,ss_clock,hold_Mexec1) ;
wire rs1_negate
;
Mflipflop_1 rs1_negate_reg_1(rs1_negate,nrs1_negate,ss_clock,hold_Mexec1) ;
wire rs1_negate_l
;
Mflipflop_1 rs1_negate_l_reg_1(rs1_negate_l,nrs1_negate_l,ss_clock,hold_Mexec1) ;
wire e_not_negmul
;
Mflipflop_1 e_not_negmul_reg_1(e_not_negmul,next_e_not_negmul,ss_clock,hold_Mexec1) ;
wire sel_w_mult
;
Mflipflop_1 sel_w_mult_reg_1(sel_w_mult,nsel_w_mult,ss_clock,hold_Mexec1) ;
wire sel_w_mult_l_b
;
Mflipflop_1 sel_w_mult_l_b_reg_1(sel_w_mult_l_b,nsel_w_mult_l_b,ss_clock,hold_Mexec1) ;
wire sel_w_mult_l_not_b
;
Mflipflop_1 sel_w_mult_l_not_b_reg_1(sel_w_mult_l_not_b, nsel_w_mult_l_not_b,ss_clock,hold_Mexec1) ;
/*
These mux selects are buffered in the DP with a special
cell that turns the select off when ss_scan_mode turns
on. Some selects turn ON when ss_scan_mode turns on.
*/
// for src1_shftpassclr_mux and part of alus1_bot_mux
wire spc_mux_default_sm
= spc_mux_default & ~ss_scan_mode;
wire rs1_double_sm
= rs1_double & ~ss_scan_mode;
wire rs1_clear_sm
= rs1_clear | ss_scan_mode;
// for alus1_top_mux
wire alus1_rfm_b3m_sm
= alus1_rfm_b3m & ~ss_scan_mode;
wire alus1_b2m_sm
= alus1_b2m & ~ss_scan_mode;
wire alus1_b1m_sm
= alus1_b1m & ~ss_scan_mode;
wire alus1_setm_sm
= alus1_setm | ss_scan_mode;
wire alus1_b2_shift_sm
= alus1_b2_shift & ~ss_scan_mode;
wire sel_rs1_shiftin_sm
= sel_rs1_shiftin & ~ss_scan_mode;
// for alus1_bot_mux (see src1_shftpassclr_mux for the rest)
wire rs1_pass_sm
= rs1_pass & ~ss_scan_mode;
wire alus1_datam_sm
= alus1_datam & ~ss_scan_mode;
// alus1_high_mux scan gating is done in Mdecode
// for alu_s2_mux_top
wire a2top_default_sm
= a2top_default & ~ss_scan_mode;
wire alus2_b2m_sm
= alus2_b2m & ~ss_scan_mode;
wire alus2_b1m_sm
= alus2_b1m & ~ss_scan_mode;
wire sel_srl2_mult_sm
= sel_srl2_mult | ss_scan_mode;
// for alus2_bot_mux
wire rs2_passit_sm
= rs2_passit | ss_scan_mode;
wire rs2_clear_sm
= rs2_clear & ~ss_scan_mode;
wire alus2_datam_sm
= alus2_datam & ~ss_scan_mode;
// alu_s2_high_mux scan gating is done in Mdecode
// for muls_shifter mux
wire e_not_negmul_sm
= e_not_negmul | ss_scan_mode;
wire rs1_negate_sm
= rs1_negate & ~ss_scan_mode;
wire e_mulsm_sm
= e_mulsm & ~ss_scan_mode;
// for alu_s2im_mux and alu_s2im_mux_ext
wire sel_w_mult_l_b_sm
= sel_w_mult_l_b | ss_scan_mode;
wire sel_w_mult_l_not_b_sm
= sel_w_mult_l_not_b & ~ss_scan_mode;
wire sel_w_mult_sm
= sel_w_mult & ~ss_scan_mode;
// for pcspec_mux
wire rdtpcm_sm
= rdtpcm & ~ss_scan_mode;
wire e_jmpcallm_sm
= e_jmpcallm & ~ss_scan_mode;
wire e_rdpsrm_sm
= e_rdpsrm & ~ss_scan_mode;
wire e_rdwimm_sm
= e_rdwimm & ~ss_scan_mode;
wire e_rdym_sm
= e_rdym & ~ss_scan_mode;
wire e_rdtbrm_sm
= e_rdtbrm & ~ss_scan_mode;
wire sel_pcspec_l_sm
= sel_pcspec_l | ss_scan_mode;
// these selects are in Mpsr
wire TRAP_sm
= TRAP | ss_scan_mode;
wire w_wrpsr_sm
= w_wrpsr & ~ss_scan_mode;
wire cwp_inc_sm
= cwp_inc & ~ss_scan_mode;
wire cwp_dec_sm
= cwp_dec & ~ss_scan_mode;
wire cwp_hold_sm
= cwp_hold & ~ss_scan_mode;
wire ecwp_next_sm
= ecwp_next & ~ss_scan_mode;
wire clret_sets_sm
= clret_sets & ~ss_scan_mode;
wire setet_ps2s_sm
= setet_ps2s & ~ss_scan_mode;
wire write_etps_sm
= write_etps & ~ss_scan_mode;
wire hold_ets_sm
= hold_ets | ss_scan_mode;
wire s_into_ps_sm
= s_into_ps | ss_scan_mode;
wire hold_ps_sm
= hold_ps & ~ss_scan_mode;
// these hold terms should be in the SPR slice
wire hold_Wreg_real
= hold_Wreg | hold_Mexec1;
wire alu_s2_reg_hold_real
= alu_s2_reg_hold | hold_Mexec1;
/*
* need to push the shiftin_a ahead one cycle for timing reasons.
* we can use the straight cc_next from psr.v since due to the
* way we mux cc_next, cc_next in the D of a mulscc is the same
* as ccm in the E of the mulscc
*/
wire nshiftin_a
= cc_next3 ^ cc_next1;
wire shiftin_a
;
Mflipflop_1 shiftin_a_reg_1(shiftin_a,nshiftin_a,ss_clock,hold_Mexec1) ;
/*
* do clock gating of RF WE here - not for warthog
wire rf_we = ~ss_clock_early & almost_rf_we;
*/
// IMMEDIATE DATA SIGN EXTENDER
wire [31:0] simm32m
= {{19{disp22[12]}}, disp22[12:0]};
// also must do the same for the 2 hi bits - imul and idiv
wire [33:32] src1_shftpassclr_hi
;
// Expanded macro begin.
// cmux3d(src1_shftpassclr_mux, 2, src1_shftpassclr_hi, ({msign_bit,msign_bit}), spc_mux_default_sm, ({msign_bit,src1m[31]}), rs1_double_sm, 2'b0, rs1_clear_sm)
function [2:1] src1_shftpassclr_mux ;
input [2:1] in0_fn ;
input s0_fn ;
input [2:1] in1_fn ;
input s1_fn ;
input [2:1] in2_fn ;
input s2_fn ;
reg [2:1] out_fn ;
begin
case ({ rs1_clear_sm, rs1_double_sm, spc_mux_default_sm}) /* synopsys parallel_case */
3'b001: out_fn = in0_fn;
3'b010: out_fn = in1_fn;
3'b100: out_fn = in2_fn;
default: out_fn = 65'hx;
endcase
src1_shftpassclr_mux = out_fn ;
end
endfunction
assign src1_shftpassclr_hi = src1_shftpassclr_mux( ({msign_bit,msign_bit}), spc_mux_default_sm, ({msign_bit,src1m[31]}), rs1_double_sm, 2'b0, rs1_clear_sm) ;
// synopsys translate_off
always @ (posedge(~Mclocks.clock))
#1 if (( rs1_clear_sm+ rs1_double_sm+ spc_mux_default_sm !== 1) & `SS_SCOPE.input_reset_l &
~Mtask.trace.ppr & ~( rs1_clear_sm+ rs1_double_sm^ spc_mux_default_sm===1'bx)) begin
$display("### %m.src1_shftpassclr_mux: CMUX3D select error!\n");
$display(" rs1_clear_sm, rs1_double_sm, spc_mux_default_sm=%0d%0d%0d\n", rs1_clear_sm, rs1_double_sm, spc_mux_default_sm);
Mclocks.warning_count = Mclocks.warning_count + 1;
end
// synopsys translate_on
// Expanded macro end.
// select on msign_bit,msign_bit was rs1_pass
// SOURCE 1 INPUT MUX
// First, the main 32 bit path
wire [31:0] disp_extended
= {disp22, 10'b0}; // simplify mux argument
// wire [31:0] temp_rf_src1;
// CMUX2(temp_rf_src1_mux,32,temp_rf_src1, // src1m,rfwrdata,alus1_b3m_sm)
// wire rf_byp = alus1_rfm_b3m_sm | alus1_b3m_sm;
wire [31:0] alu_s1_mux_top
;
// was temp_rf_src1
// Expanded macro begin.
// cmux6d(alus1_top_mux, 32, alu_s1_mux_top, src1m, alus1_rfm_b3m_sm, alu_shift, alus1_b1m_sm, disp_extended, alus1_setm_sm, result, alus1_b2m_sm, ({result[30:0],W_alushift_out[31]}), alus1_b2_shift_sm, ({alu_shift[30:0],result[31]}), sel_rs1_shiftin_sm)
function [32:1] alus1_top_mux ;
input [32:1] in0_fn ;
input s0_fn ;
input [32:1] in1_fn ;
input s1_fn ;
input [32:1] in2_fn ;
input s2_fn ;
input [32:1] in3_fn ;
input s3_fn ;
input [32:1] in4_fn ;
input s4_fn ;
input [32:1] in5_fn ;
input s5_fn ;
reg [32:1] out_fn ;
begin
case ({ sel_rs1_shiftin_sm, alus1_b2_shift_sm, alus1_b2m_sm, alus1_setm_sm, alus1_b1m_sm, alus1_rfm_b3m_sm}) /* synopsys parallel_case */
6'b000001: out_fn = in0_fn ;
6'b000010: out_fn = in1_fn ;
6'b000100: out_fn = in2_fn ;
6'b001000: out_fn = in3_fn ;
6'b010000: out_fn = in4_fn ;
6'b100000: out_fn = in5_fn ;
default: out_fn = 65'hx;
endcase
alus1_top_mux = out_fn ;
end
endfunction
assign alu_s1_mux_top = alus1_top_mux( src1m, alus1_rfm_b3m_sm, alu_shift, alus1_b1m_sm, disp_extended, alus1_setm_sm, result,
alus1_b2m_sm, ({result[30:0],W_alushift_out[31]}), alus1_b2_shift_sm, ({alu_shift[30:0],result[31]}), sel_rs1_shiftin_sm) ;
// synopsys translate_off
always @ (posedge(~Mclocks.clock))
#1 if (( sel_rs1_shiftin_sm+ alus1_b2_shift_sm+ alus1_b2m_sm+ alus1_setm_sm+ alus1_b1m_sm+ alus1_rfm_b3m_sm !== 1) & `SS_SCOPE.input_reset_l &
~Mtask.trace.ppr & ~( sel_rs1_shiftin_sm+ alus1_b2_shift_sm+ alus1_b2m_sm+ alus1_setm_sm+ alus1_b1m_sm^ alus1_rfm_b3m_sm===1'bx)) begin
$display("### %m.alus1_top_mux: CMUX6D select error!\n");
$display(" sel_rs1_shiftin_sm, alus1_b2_shift_sm, alus1_b2m_sm, alus1_setm_sm, alus1_b1m_sm, alus1_rfm_b3m_sm=%0d%0d%0d%0d%0d%0d\n", sel_rs1_shiftin_sm, alus1_b2_shift_sm, alus1_b2m_sm, alus1_setm_sm, alus1_b1m_sm, alus1_rfm_b3m_sm);
Mclocks.warning_count = Mclocks.warning_count + 1;
end
// synopsys translate_on
// Expanded macro end.
wire rs1_high
= alu_s1_mux_top[31] & pass_hi_rs1;
wire [31:0] alu_s1_mux
;
// Expanded macro begin.
// cmux4d(alus1_bot_mux, 32, alu_s1_mux, ({rs1_high,alu_s1_mux_top[30:0]}), rs1_pass_sm, ({alu_s1_mux_top[30:0], 1'b0}), rs1_double_sm, 32'b0, rs1_clear_sm, ld_iu, alus1_datam_sm)
function [32:1] alus1_bot_mux ;
input [32:1] in0_fn ;
input s0_fn ;
input [32:1] in1_fn ;
input s1_fn ;
input [32:1] in2_fn ;
input s2_fn ;
input [32:1] in3_fn ;
input s3_fn ;
reg [32:1] out_fn ;
begin
case ({ alus1_datam_sm, rs1_clear_sm, rs1_double_sm, rs1_pass_sm}) /* synopsys parallel_case */
4'b0001: out_fn = in0_fn;
4'b0010: out_fn = in1_fn;
4'b0100: out_fn = in2_fn;
4'b1000: out_fn = in3_fn;
default: out_fn = 65'hx;
endcase
alus1_bot_mux = out_fn ;
end
endfunction
assign alu_s1_mux = alus1_bot_mux( ({rs1_high,alu_s1_mux_top[30:0]}), rs1_pass_sm, ({alu_s1_mux_top[30:0], 1'b0}), rs1_double_sm, 32'b0, rs1_clear_sm, ld_iu, alus1_datam_sm) ;
// synopsys translate_off
always @ (posedge(~Mclocks.clock))
#1 if (( alus1_datam_sm+ rs1_clear_sm+ rs1_double_sm+ rs1_pass_sm !== 1) & `SS_SCOPE.input_reset_l &
~Mtask.trace.ppr & ~( alus1_datam_sm+ rs1_clear_sm+ rs1_double_sm^ rs1_pass_sm===1'bx)) begin
$display("### %m.alus1_bot_mux: CMUX4D select error!\n");
$display(" alus1_datam_sm, rs1_clear_sm, rs1_double_sm, rs1_pass_sm=%0d%0d%0d%0d\n", alus1_datam_sm, rs1_clear_sm, rs1_double_sm, rs1_pass_sm);
Mclocks.warning_count = Mclocks.warning_count + 1;
end
// synopsys translate_on
// Expanded macro end.
wire [31:0] alu_s1m
;
Mflipflop_32 alu_s1_reg_32( alu_s1m, alu_s1_mux, ss_clock, hold_Mexec1) ;
// was held by alu_s1_reg_hold
// Now, the pasted on 2 bit path
// wire dsign_bit1 = result[31] & signed_div;
wire [1:0] nsrc1_high2
;
// Expanded macro begin.
// cmux3d(alus1_high_mux, 2, nsrc1_high2, ({dsign_bit1,dsign_bit1}), use_hi_y, ({high_2[1],alu_shift[31]}), use_hi_alu, src1_shftpassclr_hi[33:32], use_hi_rs1_default)
function [2:1] alus1_high_mux ;
input [2:1] in0_fn ;
input s0_fn ;
input [2:1] in1_fn ;
input s1_fn ;
input [2:1] in2_fn ;
input s2_fn ;
reg [2:1] out_fn ;
begin
case ({ use_hi_rs1_default, use_hi_alu, use_hi_y}) /* synopsys parallel_case */
3'b001: out_fn = in0_fn;
3'b010: out_fn = in1_fn;
3'b100: out_fn = in2_fn;
default: out_fn = 65'hx;
endcase
alus1_high_mux = out_fn ;
end
endfunction
assign nsrc1_high2 = alus1_high_mux( ({dsign_bit1,dsign_bit1}), use_hi_y, ({high_2[1],alu_shift[31]}), use_hi_alu, src1_shftpassclr_hi[33:32], use_hi_rs1_default) ;
// synopsys translate_off
always @ (posedge(~Mclocks.clock))
#1 if (( use_hi_rs1_default+ use_hi_alu+ use_hi_y !== 1) & `SS_SCOPE.input_reset_l &
~Mtask.trace.ppr & ~( use_hi_rs1_default+ use_hi_alu^ use_hi_y===1'bx)) begin
$display("### %m.alus1_high_mux: CMUX3D select error!\n");
$display(" use_hi_rs1_default, use_hi_alu, use_hi_y=%0d%0d%0d\n", use_hi_rs1_default, use_hi_alu, use_hi_y);
Mclocks.warning_count = Mclocks.warning_count + 1;
end
// synopsys translate_on
// Expanded macro end.
wire [33:32] alu_s1_high_regout
;
Mflipflop_2 alu_s1_high_reg_2(alu_s1_high_regout,nsrc1_high2,ss_clock,hold_Mexec1) ;
wire [33:32] alu_s1_high
;
// Expanded macro begin.
// cmux2d(alu_s1_high_mux, 2, alu_s1_high, alu_s1_high_regout, rs1_negate_l, ~alu_s1_high_regout, rs1_negate)
function [2:1] alu_s1_high_mux ;
input [2:1] in0_fn ;
input s0_fn ;
input [2:1] in1_fn ;
input s1_fn ;
reg [2:1] out_fn ;
begin
case ({ rs1_negate, rs1_negate_l}) /* synopsys parallel_case */
2'b01: out_fn = in0_fn;
2'b10: out_fn = in1_fn;
default: out_fn = 65'hx;
endcase
alu_s1_high_mux = out_fn ;
end
endfunction
assign alu_s1_high = alu_s1_high_mux( alu_s1_high_regout, rs1_negate_l, ~alu_s1_high_regout, rs1_negate) ;
// synopsys translate_off
always @ (posedge(~Mclocks.clock))
#1 if (( rs1_negate+ rs1_negate_l !== 1) & `SS_SCOPE.input_reset_l &
~Mtask.trace.ppr & ~( rs1_negate^ rs1_negate_l===1'bx)) begin
$display("### %m.alu_s1_high_mux: CMUX2D select error!\n");
$display(" rs1_negate, rs1_negate_l=%0d%0d\n", rs1_negate, rs1_negate_l);
Mclocks.warning_count = Mclocks.warning_count + 1;
end
// synopsys translate_on
// Expanded macro end.
// ALU_S10M this interface signal
wire alu_s1m_0 = alu_s1m[0];
// temp mux
// wire [31:0] temp_rf_src2;
// CMUX2(temp_rf_src2_mux,32,temp_rf_src2, // src2m, rfwrdata, alus2_b3m_sm)
// SRC2 FROM RF and IMM data MUST be selectively cleared for IMUL.
// need to be able to selectively set the LSBit for IDIV ovf calculation
wire [31:0] rf2_imm_data
;
// Expanded macro begin.
// cmux2d(rf2_imm_data_mux, 32, rf2_imm_data, simm32m, d_imm, src2m, d_imm_l)
function [32:1] rf2_imm_data_mux ;
input [32:1] in0_fn ;
input s0_fn ;
input [32:1] in1_fn ;
input s1_fn ;
reg [32:1] out_fn ;
begin
case ({ d_imm_l, d_imm}) /* synopsys parallel_case */
2'b01: out_fn = in0_fn;
2'b10: out_fn = in1_fn;
default: out_fn = 65'hx;
endcase
rf2_imm_data_mux = out_fn ;
end
endfunction
assign rf2_imm_data = rf2_imm_data_mux( simm32m, d_imm, src2m, d_imm_l) ;
// synopsys translate_off
always @ (posedge(~Mclocks.clock))
#1 if (( d_imm_l+ d_imm !== 1) & `SS_SCOPE.input_reset_l &
~Mtask.trace.ppr & ~( d_imm_l^ d_imm===1'bx)) begin
$display("### %m.rf2_imm_data_mux: CMUX2D select error!\n");
$display(" d_imm_l, d_imm=%0d%0d\n", d_imm_l, d_imm);
Mclocks.warning_count = Mclocks.warning_count + 1;
end
// synopsys translate_on
// Expanded macro end.
// src2m, d_imm_l) // was temp_rf_src2
// SOURCE 2 INPUT MUX
wire [31:0] alu_s2_mux_top
;
// Expanded macro begin.
// cmux4d(alus2_top_mux, 32, alu_s2_mux_top, rf2_imm_data, a2top_default_sm, result, alus2_b2m_sm, alu_shift, alus2_b1m_sm, ({alu_shift[1:0],alu_s2m[31:2]}), sel_srl2_mult_sm)
function [32:1] alus2_top_mux ;
input [32:1] in0_fn ;
input s0_fn ;
input [32:1] in1_fn ;
input s1_fn ;
input [32:1] in2_fn ;
input s2_fn ;
input [32:1] in3_fn ;
input s3_fn ;
reg [32:1] out_fn ;
begin
case ({ sel_srl2_mult_sm, alus2_b1m_sm, alus2_b2m_sm, a2top_default_sm}) /* synopsys parallel_case */
4'b0001: out_fn = in0_fn;
4'b0010: out_fn = in1_fn;
4'b0100: out_fn = in2_fn;
4'b1000: out_fn = in3_fn;
default: out_fn = 65'hx;
endcase
alus2_top_mux = out_fn ;
end
endfunction
assign alu_s2_mux_top = alus2_top_mux( rf2_imm_data, a2top_default_sm, result, alus2_b2m_sm, alu_shift, alus2_b1m_sm, ({alu_shift[1:0],alu_s2m[31:2]}), sel_srl2_mult_sm) ;
// synopsys translate_off
always @ (posedge(~Mclocks.clock))
#1 if (( sel_srl2_mult_sm+ alus2_b1m_sm+ alus2_b2m_sm+ a2top_default_sm !== 1) & `SS_SCOPE.input_reset_l &
~Mtask.trace.ppr & ~( sel_srl2_mult_sm+ alus2_b1m_sm+ alus2_b2m_sm^ a2top_default_sm===1'bx)) begin
$display("### %m.alus2_top_mux: CMUX4D select error!\n");
$display(" sel_srl2_mult_sm, alus2_b1m_sm, alus2_b2m_sm, a2top_default_sm=%0d%0d%0d%0d\n", sel_srl2_mult_sm, alus2_b1m_sm, alus2_b2m_sm, a2top_default_sm);
Mclocks.warning_count = Mclocks.warning_count + 1;
end
// synopsys translate_on
// Expanded macro end.
// a2top_default was alus2_rfm_im_b3m
// rfwrdata, alus2_b3m_sm,
wire [31:0] alu_s2_mux
;
// Expanded macro begin.
// cmux3d(alus2_bot_mux, 32, alu_s2_mux, alu_s2_mux_top, rs2_passit, 32'b0, rs2_clear, ld_iu, alus2_datam)
function [32:1] alus2_bot_mux ;
input [32:1] in0_fn ;
input s0_fn ;
input [32:1] in1_fn ;
input s1_fn ;
input [32:1] in2_fn ;
input s2_fn ;
reg [32:1] out_fn ;
begin
case ({ alus2_datam, rs2_clear, rs2_passit}) /* synopsys parallel_case */
3'b001: out_fn = in0_fn;
3'b010: out_fn = in1_fn;
3'b100: out_fn = in2_fn;
default: out_fn = 65'hx;
endcase
alus2_bot_mux = out_fn ;
end
endfunction
assign alu_s2_mux = alus2_bot_mux( alu_s2_mux_top, rs2_passit, 32'b0, rs2_clear, ld_iu, alus2_datam) ;
// synopsys translate_off
always @ (posedge(~Mclocks.clock))
#1 if (( alus2_datam+ rs2_clear+ rs2_passit !== 1) & `SS_SCOPE.input_reset_l &
~Mtask.trace.ppr & ~( alus2_datam+ rs2_clear^ rs2_passit===1'bx)) begin
$display("### %m.alus2_bot_mux: CMUX3D select error!\n");
$display(" alus2_datam, rs2_clear, rs2_passit=%0d%0d%0d\n", alus2_datam, rs2_clear, rs2_passit);
Mclocks.warning_count = Mclocks.warning_count + 1;
end
// synopsys translate_on
// Expanded macro end.
Mflipflop_32 alu_s2_reg_32( alu_s2m, alu_s2_mux, ss_clock, alu_s2_reg_hold_real) ;
// ext_bits reg for IMUL (high 2 bits)
wire rf2_imm_data_msb = rf2_imm_data[31];
wire [1:0] nsrc2_high2
;
// Expanded macro begin.
// cmux4d(alu_s2_high_mux_mux, 2, nsrc2_high2, ({dsign_bit2,dsign_bit2}), use_hi_rs2, ({alu_s1m[0],alu_s1m[0]}), use_low_rs1, ({high_2[1],high_2[1]}), use_hi_rs2_default, 2'b0, not_rs2_rs1_default)
function [2:1] alu_s2_high_mux_mux ;
input [2:1] in0_fn ;
input s0_fn ;
input [2:1] in1_fn ;
input s1_fn ;
input [2:1] in2_fn ;
input s2_fn ;
input [2:1] in3_fn ;
input s3_fn ;
reg [2:1] out_fn ;
begin
case ({ not_rs2_rs1_default, use_hi_rs2_default, use_low_rs1, use_hi_rs2}) /* synopsys parallel_case */
4'b0001: out_fn = in0_fn;
4'b0010: out_fn = in1_fn;
4'b0100: out_fn = in2_fn;
4'b1000: out_fn = in3_fn;
default: out_fn = 65'hx;
endcase
alu_s2_high_mux_mux = out_fn ;
end
endfunction
assign nsrc2_high2 = alu_s2_high_mux_mux( ({dsign_bit2,dsign_bit2}), use_hi_rs2, ({alu_s1m[0],alu_s1m[0]}), use_low_rs1, ({high_2[1],high_2[1]}), use_hi_rs2_default, 2'b0, not_rs2_rs1_default) ;
// synopsys translate_off
always @ (posedge(~Mclocks.clock))
#1 if (( not_rs2_rs1_default+ use_hi_rs2_default+ use_low_rs1+ use_hi_rs2 !== 1) & `SS_SCOPE.input_reset_l &
~Mtask.trace.ppr & ~( not_rs2_rs1_default+ use_hi_rs2_default+ use_low_rs1^ use_hi_rs2===1'bx)) begin
$display("### %m.alu_s2_high_mux_mux: CMUX4D select error!\n");
$display(" not_rs2_rs1_default, use_hi_rs2_default, use_low_rs1, use_hi_rs2=%0d%0d%0d%0d\n", not_rs2_rs1_default, use_hi_rs2_default, use_low_rs1, use_hi_rs2);
Mclocks.warning_count = Mclocks.warning_count + 1;
end
// synopsys translate_on
// Expanded macro end.
wire [33:32] ext_bits_pre
;
Mflipflop_2 ext_bits_reg_2(ext_bits_pre,nsrc2_high2,ss_clock,hold_Mexec1) ;
// SOURCE 1 MULScc INPUT SHIFTER
// pushed ahead one cycle - is since ccm in E of mulscc is *guaranteed*
// to be cc_next in D of mulscc due to structure of cc_next mux (psr.v)
// wire shiftin_a = ccm[3] ^ ccm[1];
wire [31:0] alu_s1sm
;
// Expanded macro begin.
// cmux3d(muls_shifter, 32, alu_s1sm, alu_s1m[31:0], e_not_negmul_sm, ~alu_s1m[31:0], rs1_negate_sm, ({shiftin_a, alu_s1m[31:1]}), e_mulsm_sm)
function [32:1] muls_shifter ;
input [32:1] in0_fn ;
input s0_fn ;
input [32:1] in1_fn ;
input s1_fn ;
input [32:1] in2_fn ;
input s2_fn ;
reg [32:1] out_fn ;
begin
case ({ e_mulsm_sm, rs1_negate_sm, e_not_negmul_sm}) /* synopsys parallel_case */
3'b001: out_fn = in0_fn;
3'b010: out_fn = in1_fn;
3'b100: out_fn = in2_fn;
default: out_fn = 65'hx;
endcase
muls_shifter = out_fn ;
end
endfunction
assign alu_s1sm = muls_shifter( alu_s1m[31:0], e_not_negmul_sm, ~alu_s1m[31:0], rs1_negate_sm, ({shiftin_a, alu_s1m[31:1]}), e_mulsm_sm) ;
// synopsys translate_off
always @ (posedge(~Mclocks.clock))
#1 if (( e_mulsm_sm+ rs1_negate_sm+ e_not_negmul_sm !== 1) & `SS_SCOPE.input_reset_l &
~Mtask.trace.ppr & ~( e_mulsm_sm+ rs1_negate_sm^ e_not_negmul_sm===1'bx)) begin
$display("### %m.muls_shifter: CMUX3D select error!\n");
$display(" e_mulsm_sm, rs1_negate_sm, e_not_negmul_sm=%0d%0d%0d\n", e_mulsm_sm, rs1_negate_sm, e_not_negmul_sm);
Mclocks.warning_count = Mclocks.warning_count + 1;
end
// synopsys translate_on
// Expanded macro end.
// SOURCE 1 INPUT SLAVe LATCH
wire [1:0] alu_s1s_lsb2 = alu_s1sm[1:0];
wire [31:0] newsrc2data
= ~alu_s2m;
wire [1:0] not_ext_bits_pre
= ~ext_bits_pre;
wire [31:0] alu_s2im
;
wire [1:0] ext_bits
;
// Expanded macro begin.
// cmux3d(alu_s2im_mux, 32, alu_s2im, alu_s2m, sel_w_mult_l_b_sm, newsrc2data, sel_w_mult_l_not_b_sm, ({result_high2,W_alushift_out[31:2]}), sel_w_mult_sm)
function [32:1] alu_s2im_mux ;
input [32:1] in0_fn ;
input s0_fn ;
input [32:1] in1_fn ;
input s1_fn ;
input [32:1] in2_fn ;
input s2_fn ;
reg [32:1] out_fn ;
begin
case ({ sel_w_mult_sm, sel_w_mult_l_not_b_sm, sel_w_mult_l_b_sm}) /* synopsys parallel_case */
3'b001: out_fn = in0_fn;
3'b010: out_fn = in1_fn;
3'b100: out_fn = in2_fn;
default: out_fn = 65'hx;
endcase
alu_s2im_mux = out_fn ;
end
endfunction
assign alu_s2im = alu_s2im_mux( alu_s2m, sel_w_mult_l_b_sm, newsrc2data, sel_w_mult_l_not_b_sm, ({result_high2,W_alushift_out[31:2]}), sel_w_mult_sm) ;
// synopsys translate_off
always @ (posedge(~Mclocks.clock))
#1 if (( sel_w_mult_sm+ sel_w_mult_l_not_b_sm+ sel_w_mult_l_b_sm !== 1) & `SS_SCOPE.input_reset_l &
~Mtask.trace.ppr & ~( sel_w_mult_sm+ sel_w_mult_l_not_b_sm^ sel_w_mult_l_b_sm===1'bx)) begin
$display("### %m.alu_s2im_mux: CMUX3D select error!\n");
$display(" sel_w_mult_sm, sel_w_mult_l_not_b_sm, sel_w_mult_l_b_sm=%0d%0d%0d\n", sel_w_mult_sm, sel_w_mult_l_not_b_sm, sel_w_mult_l_b_sm);
Mclocks.warning_count = Mclocks.warning_count + 1;
end
// synopsys translate_on
// Expanded macro end.
// Expanded macro begin.
// cmux3d(alu_s2im_mux_ext, 2, ext_bits, ext_bits_pre, sel_w_mult_l_b_sm, not_ext_bits_pre, sel_w_mult_l_not_b_sm, ext_bits_pre, sel_w_mult_sm)
function [2:1] alu_s2im_mux_ext ;
input [2:1] in0_fn ;
input s0_fn ;
input [2:1] in1_fn ;
input s1_fn ;
input [2:1] in2_fn ;
input s2_fn ;
reg [2:1] out_fn ;
begin
case ({ sel_w_mult_sm, sel_w_mult_l_not_b_sm, sel_w_mult_l_b_sm}) /* synopsys parallel_case */
3'b001: out_fn = in0_fn;
3'b010: out_fn = in1_fn;
3'b100: out_fn = in2_fn;
default: out_fn = 65'hx;
endcase
alu_s2im_mux_ext = out_fn ;
end
endfunction
assign ext_bits = alu_s2im_mux_ext( ext_bits_pre, sel_w_mult_l_b_sm, not_ext_bits_pre, sel_w_mult_l_not_b_sm, ext_bits_pre, sel_w_mult_sm) ;
// synopsys translate_off
always @ (posedge(~Mclocks.clock))
#1 if (( sel_w_mult_sm+ sel_w_mult_l_not_b_sm+ sel_w_mult_l_b_sm !== 1) & `SS_SCOPE.input_reset_l &
~Mtask.trace.ppr & ~( sel_w_mult_sm+ sel_w_mult_l_not_b_sm^ sel_w_mult_l_b_sm===1'bx)) begin
$display("### %m.alu_s2im_mux_ext: CMUX3D select error!\n");
$display(" sel_w_mult_sm, sel_w_mult_l_not_b_sm, sel_w_mult_l_b_sm=%0d%0d%0d\n", sel_w_mult_sm, sel_w_mult_l_not_b_sm, sel_w_mult_l_b_sm);
Mclocks.warning_count = Mclocks.warning_count + 1;
end
// synopsys translate_on
// Expanded macro end.
// SOURCE 2 INPUT SLAVe LATCH
wire [4:0] alu_s2i_cnt
= alu_s2m[4:0];
// ALU and CC
wire [31:0] alu_out
;
wire [4:0] alu_out_lsb5 = alu_out[4:0]; // used for address
// alignment check, and
// illegal CWP check
wire [33:0] big_alu_out
;
wire ccN
, ccZ
, ccV
, ccC
;
wire [33:0] A
= {alu_s1_high,alu_s1sm};
wire [33:0] B
= {ext_bits, alu_s2im};
wire [31:0] dummy
; // dummy port to satisfy mentor tools
alu34 alucc (big_alu_out, ccN, ccZ, ccV, ccC,
A, B,
carry_in, alu_ADD, alu_AND, alu_XNOR,
alu_sub, tagged_ovf,
// random junk
~alu_ADD, alu_ADD, ~alu_ADD, dummy);
// note for timing - the control logic expects alu_cc_next[3:2] to
// be inverted
wire nectccV
= (ccV & ~eopc_hidiv3)
| (eopc_hidiv3 & det_divovf);
wire nextccC
= ccC & ~eopc_hidiv3;
wire [3:0] alu_cc_next = {~ccN, ~ccZ, ccV, nextccC};
// 9-15-96 add non-inverting port for ccN, ccZ to speed up
// path of alu_cc_next to Mdecode block.
assign ccN_noninv = ccN;
assign ccZ_noninv = ccZ;
This page: |
Created: | Thu Aug 19 12:03:16 1999 |
| From: |
../../../sparc_v8/ssparc/iu/Mexec/rtl/exec.v
|