// @(#)iutrace.v 1.49 4/22/93
/*
This module contains code to create IU instruction traces.
It supports functional and gate-level IU models.
*/
// @(#)cells.h 1.12 5/28/93 93/05/28
// cells.h
// Translate controls for Synopsys come in comments, which cpp will strip out.
// The following macros are deleted for Verilog (cells.h, this file) but
// expanded by m4 for Synopsys (syn_cells.h & synopsys.h).
// We are modifying Suntan to go from a latched based design
// to a register based design. To do this quickly, as a first
// pass, change all master latches to registers, and all slaves
// to buffers.
// Support for 'run -unit scan2' (scan state load/dump). The file
// $DESIGNDIR/lib/ffdef.h will be created by the run script. If
// ffdef.h is empty, macro expansion will be normal; if it contains
// a definition for the cpp variable MODULE_FF, then flipflops will
// be expanded into module instances instead of in-line code.
//
// Note: Modules that use the FF macros below in -unit scan2 simulations
// *must* contain a net called ss_scan_mode . This net must be driven
// by the internal scan chain scan mode signal if the flops are part
// of the internal scan chain; otherwise this net must be tied to 0.
//
// Flipflops will expand into inline code (the normal case for simulation)
// m4 doesn't work on the rest of this file with the usual quotes
// because these are used by verilog defines.
// change the quotes to very unlikely characters.
// also have to .
module Mcomplete
(inst_complete, end_diagnostic, clock, hold, scan_mode);
output inst_complete
; // indicates completion of an instr.
output end_diagnostic
; // indicates the end of a diagnostic
input clock
;
input hold
;
input scan_mode
;
wire w_cycle_trap
;
wire IU_in_trap
= `Mdecode.IU_in_trap;
wire fold_in_e
= `Mdecode.pc_cntl.fold_in_e
& ~IU_in_trap;
reg fold_in_w
;
reg [(1)-1:0] fiw_regmaster
; always @ (posedge (clock )) begin if ((hold | scan_mode)===1'b0) fiw_regmaster
= fold_in_e; else if ((hold | scan_mode)===1'b1) fiw_regmaster
= fold_in_w; else fiw_regmaster
= 65'bx; if((clock) === 1'bx) #1 fold_in_w = 65'bx; else #1 fold_in_w = fiw_regmaster
; end
reg fold_in_r
;
reg [(1)-1:0] fir_regmaster
; always @ (posedge (clock )) begin if ((hold | scan_mode)===1'b0) fir_regmaster
= fold_in_w; else if ((hold | scan_mode)===1'b1) fir_regmaster
= fold_in_r; else fir_regmaster
= 65'bx; if((clock) === 1'bx) #1 fold_in_r = 65'bx; else #1 fold_in_r = fir_regmaster
; end
wire fold_annul_e
= `Mdecode.pc_cntl.fold_annul
& ~w_cycle_trap;
reg fold_annul_w
;
reg [(1)-1:0] faw_regmaster
; always @ (posedge (clock )) begin if ((hold | scan_mode)===1'b0) faw_regmaster
= fold_annul_e; else if ((hold | scan_mode)===1'b1) faw_regmaster
= fold_annul_w; else faw_regmaster
= 65'bx; if((clock) === 1'bx) #1 fold_annul_w = 65'bx; else #1 fold_annul_w = faw_regmaster
; end
reg fold_annul_r
;
reg [(1)-1:0] far_regmaster
; always @ (posedge (clock )) begin if ((hold | scan_mode)===1'b0) far_regmaster
= fold_annul_w; else if ((hold | scan_mode)===1'b1) far_regmaster
= fold_annul_r; else far_regmaster
= 65'bx; if((clock) === 1'bx) #1 fold_annul_r = 65'bx; else #1 fold_annul_r = far_regmaster
; end
/* This is added for cycle by cycle SAS-verilog comparison.
Some signals are created just for this. Others are
pulled from other modules with modification. */
wire d_valid_decode
= `Mdecode.valid_decode;
wire load_cc
= `Mdecode.load_cc;
// wire d_cwp_inc = `Mdecode.cwp_inc;
// wire d_cwp_dec = `Mdecode.cwp_dec;
wire ec
= `Mexec.psr_mod.ecm;
wire ef
= `Mexec.psr_mod.efm;
wire [3:0] pil
= `Mexec.psr_mod.pilm;
wire s
= `Mexec.psr_mod.sm;
wire ps
= `Mexec.psr_mod.psm;
wire et
= `Mexec.psr_mod.etm;
wire [7:0] w_invalid_mask
= `Mexec.wim_mod.wimm;
wire [31:4] trap_base_reg
= `Mexec.tbr_mod.tbrm;
wire [31:0] y_reg
= `Mexec.y_mod.ym;
reg e_valid_decode
, w_valid_decode
;
reg [(1)-1:0] e_valid_decodemaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) e_valid_decodemaster
= d_valid_decode; else if (( hold)===1'b1) e_valid_decodemaster
= e_valid_decode; else e_valid_decodemaster
= 65'bx; if(( clock) === 1'bx) #1 e_valid_decode = 65'bx; else #1 e_valid_decode = e_valid_decodemaster
; end
reg [(1)-1:0] w_valid_decodemaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) w_valid_decodemaster
= e_valid_decode; else if (( hold)===1'b1) w_valid_decodemaster
= w_valid_decode; else w_valid_decodemaster
= 65'bx; if(( clock) === 1'bx) #1 w_valid_decode = 65'bx; else #1 w_valid_decode = w_valid_decodemaster
; end
// This is for gen_help. Hold dpc if there is genhelp and pipe it.
wire [31:0] d_pc
= {`Mpc.dpc, 2'b0};
wire pgen_help
= `Mdecode.pipec_help_ilock.pgen_help;
reg [31:0] e_pc
, w_pc
, r_pc_almost
;
reg [31:0] into_e_pc
;
always @ (( pgen_help) or ( d_pc) or ( e_pc)) case ( pgen_help) 0: into_e_pc = d_pc; 1: into_e_pc = e_pc; default: into_e_pc = 65'hx; endcase
reg [(32)-1:0] e_pc_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) e_pc_mastermaster
= into_e_pc; else if (( hold)===1'b1) e_pc_mastermaster
= e_pc; else e_pc_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 e_pc = 65'bx; else #1 e_pc = e_pc_mastermaster
; end
reg [(32)-1:0] w_pc_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) w_pc_mastermaster
= e_pc; else if (( hold)===1'b1) w_pc_mastermaster
= w_pc; else w_pc_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 w_pc = 65'bx; else #1 w_pc = w_pc_mastermaster
; end
reg [(32)-1:0] r_pc_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) r_pc_mastermaster
= w_pc; else if (( hold)===1'b1) r_pc_mastermaster
= r_pc_almost; else r_pc_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 r_pc_almost = 65'bx; else #1 r_pc_almost = r_pc_mastermaster
; end
// this confusion on r_pc is because we need to have the r_pc match
// the bicc's PC if the delay slot get annuled. note that for
// inst_comp
wire [31:0] r_pc
;
wire sel_rpc_dec
= fold_in_r & fold_annul_r;
wire [31:0] r_pc_dec
= r_pc_almost - ({29'b0,1'b1,2'b0});
assign r_pc = ((sel_rpc_dec)===1'b0) ? (r_pc_almost) : ( ((sel_rpc_dec)===1'b1) ? (r_pc_dec) : ( 65'hx )) ;
//n_pc should still be wpc of pc.v because it is used for traps for compare.
wire [31:0] n_pc
= {`Mpc.wpc, 2'b0};
wire [31:0] d_decode_inst
= `Mdecode.ir.in_dec;
reg [31:0] e_decode_inst
, w_decode_inst
, r_decode_inst
;
reg [(32)-1:0] e_dec_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) e_dec_mastermaster
= d_decode_inst; else if (( hold)===1'b1) e_dec_mastermaster
= e_decode_inst; else e_dec_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 e_decode_inst = 65'bx; else #1 e_decode_inst = e_dec_mastermaster
; end
reg [(32)-1:0] w_dec_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) w_dec_mastermaster
= e_decode_inst; else if (( hold)===1'b1) w_dec_mastermaster
= w_decode_inst; else w_dec_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 w_decode_inst = 65'bx; else #1 w_decode_inst = w_dec_mastermaster
; end
reg [(32)-1:0] r_dec_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) r_dec_mastermaster
= w_decode_inst; else if (( hold)===1'b1) r_dec_mastermaster
= r_decode_inst; else r_dec_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 r_decode_inst = 65'bx; else #1 r_decode_inst = r_dec_mastermaster
; end
// This stuff is supposed to duplicate the backup reg for the
// folded branch. can't just use pipeline cuz it doesn;t have all
// of the necessary bits.
wire iut_cant_unload
= `Mqueue.cant_unload;
wire iut_hld_dir2
= `Mqueue.hld_dir2_real;
wire [31:0] iut_inst_for_br
;
wire [31:0] iut_q1_entry
= `Mqueue.q1_entry;
wire iut_hld_dirreg
= `Mdecode.hld_dirreg_rf;
reg [31:0] iut_backup_bdir
;
reg [(32)-1:0] iut_backup_bdir_regmaster
; always @ (posedge (clock )) begin if ((iut_hld_dir2)===1'b0) iut_backup_bdir_regmaster
= iut_inst_for_br; else if ((iut_hld_dir2)===1'b1) iut_backup_bdir_regmaster
= iut_backup_bdir; else iut_backup_bdir_regmaster
= 65'bx; if((clock) === 1'bx) #1 iut_backup_bdir = 65'bx; else #1 iut_backup_bdir = iut_backup_bdir_regmaster
; end
assign iut_inst_for_br = ((iut_cant_unload)===1'b0) ? ( iut_q1_entry) : ( ((iut_cant_unload)===1'b1) ? (iut_backup_bdir) : ( 65'hx )) ;
reg [31:0] fold_dir
, fold_eir
, fold_wir
, fold_rir
;
reg [(32)-1:0] fold_dir_regmaster
; always @ (posedge (clock )) begin if ((iut_hld_dirreg)===1'b0) fold_dir_regmaster
= iut_inst_for_br; else if ((iut_hld_dirreg)===1'b1) fold_dir_regmaster
= fold_dir; else fold_dir_regmaster
= 65'bx; if((clock) === 1'bx) #1 fold_dir = 65'bx; else #1 fold_dir = fold_dir_regmaster
; end
reg [(32)-1:0] fold_eir_regmaster
; always @ (posedge (clock )) begin if ((hold)===1'b0) fold_eir_regmaster
= fold_dir; else if ((hold)===1'b1) fold_eir_regmaster
= fold_eir; else fold_eir_regmaster
= 65'bx; if((clock) === 1'bx) #1 fold_eir = 65'bx; else #1 fold_eir = fold_eir_regmaster
; end
reg [(32)-1:0] fold_wir_regmaster
; always @ (posedge (clock )) begin if ((hold)===1'b0) fold_wir_regmaster
= fold_eir; else if ((hold)===1'b1) fold_wir_regmaster
= fold_wir; else fold_wir_regmaster
= 65'bx; if((clock) === 1'bx) #1 fold_wir = 65'bx; else #1 fold_wir = fold_wir_regmaster
; end
reg [(32)-1:0] fold_rir_regmaster
; always @ (posedge (clock )) begin if ((hold)===1'b0) fold_rir_regmaster
= fold_wir; else if ((hold)===1'b1) fold_rir_regmaster
= fold_rir; else fold_rir_regmaster
= 65'bx; if((clock) === 1'bx) #1 fold_rir = 65'bx; else #1 fold_rir = fold_rir_regmaster
; end
// trap stuff
assign w_cycle_trap = `Mdecode.TRAP;
reg r_trap_from_w
;
reg [(1)-1:0] r_trap_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) r_trap_mastermaster
= w_cycle_trap; else if (( hold)===1'b1) r_trap_mastermaster
= r_trap_from_w; else r_trap_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 r_trap_from_w = 65'bx; else #1 r_trap_from_w = r_trap_mastermaster
; end
wire r_cycle_trap
=
~`Mdecode.ss_reset & (r_trap_from_w);
/*
* not for warthog
| `Mdecode.trapr_dae
| `Mdecode.trapr_daer
| `Mdecode.trapr_dmmum ) ;
*/
wire hold_pipe
= `Mdecode.hold;
wire d_bicc_taken
= `Mdecode.bicc_taken;
reg e_bicc_taken
, w_bicc_taken
, r_bicc_taken
;
reg [(1)-1:0] e_bicc_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) e_bicc_mastermaster
= d_bicc_taken; else if (( hold)===1'b1) e_bicc_mastermaster
= e_bicc_taken; else e_bicc_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 e_bicc_taken = 65'bx; else #1 e_bicc_taken = e_bicc_mastermaster
; end
reg [(1)-1:0] w_bicc_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) w_bicc_mastermaster
= e_bicc_taken; else if (( hold)===1'b1) w_bicc_mastermaster
= w_bicc_taken; else w_bicc_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 w_bicc_taken = 65'bx; else #1 w_bicc_taken = w_bicc_mastermaster
; end
reg [(1)-1:0] r_bicc_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) r_bicc_mastermaster
= w_bicc_taken; else if (( hold)===1'b1) r_bicc_mastermaster
= r_bicc_taken; else r_bicc_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 r_bicc_taken = 65'bx; else #1 r_bicc_taken = r_bicc_mastermaster
; end
wire d_fcc_taken
= `Mdecode.pipec_br_vald.fcc_taken;
reg e_fcc_taken
, w_fcc_taken
, r_fcc_taken
;
reg [(1)-1:0] e_fcc_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) e_fcc_mastermaster
= d_fcc_taken; else if (( hold)===1'b1) e_fcc_mastermaster
= e_fcc_taken; else e_fcc_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 e_fcc_taken = 65'bx; else #1 e_fcc_taken = e_fcc_mastermaster
; end
reg [(1)-1:0] w_fcc_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) w_fcc_mastermaster
= e_fcc_taken; else if (( hold)===1'b1) w_fcc_mastermaster
= w_fcc_taken; else w_fcc_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 w_fcc_taken = 65'bx; else #1 w_fcc_taken = w_fcc_mastermaster
; end
reg [(1)-1:0] r_fcc_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) r_fcc_mastermaster
= w_fcc_taken; else if (( hold)===1'b1) r_fcc_mastermaster
= r_fcc_taken; else r_fcc_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 r_fcc_taken = 65'bx; else #1 r_fcc_taken = r_fcc_mastermaster
; end
wire [3:0] wr_cc_next
= `Mexec.psr_mod.cc_mod.cc_next;
wire [3:0] wr_cc
= `Mexec.psr_mod.ccm;
/* This is a an implementation with mux going into psr reg. */
reg [3:0] w_alu_cc
, cc_r
;
reg [3:0] cc_w_out
;
reg w_setcc
;
wire [3:0] e_alu_cc
= `Mexec.psr_mod.cc_mod.alu_cc;
wire [3:0] w_result_cc
= `Mexec.psr_mod.cc_mod.result_cc;
wire e_setcc
= `Mdecode.special_reg_control.setcc;
wire w_wrpsr
= `Mdecode.special_reg_control.w_wrpsr;
reg [(1)-1:0] w_set_cc_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) w_set_cc_mastermaster
= e_setcc; else if (( hold)===1'b1) w_set_cc_mastermaster
= w_setcc; else w_set_cc_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 w_setcc = 65'bx; else #1 w_setcc = w_set_cc_mastermaster
; end
wire w_load_cc
= w_setcc & ~w_cycle_trap & ~r_cycle_trap;
wire w_write_cc
= w_wrpsr & ~w_cycle_trap;
wire w_hold_cc
= ~w_load_cc & ~w_write_cc;
reg [(4)-1:0] w_alu_cc_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) w_alu_cc_mastermaster
= e_alu_cc; else if (( hold)===1'b1) w_alu_cc_mastermaster
= w_alu_cc; else w_alu_cc_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 w_alu_cc = 65'bx; else #1 w_alu_cc = w_alu_cc_mastermaster
; end
always @ (( w_load_cc) or ( w_write_cc) or ( w_hold_cc) or ( w_alu_cc) or ( w_result_cc) or ( cc_r)) case ({ w_hold_cc, w_write_cc, w_load_cc}) 3'b001: cc_w_out = w_alu_cc; 3'b010: cc_w_out = w_result_cc; 3'b100: cc_w_out = cc_r; default: cc_w_out = 65'hx; endcase
reg [(4)-1:0] cc_r_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) cc_r_mastermaster
= cc_w_out; else if (( hold)===1'b1) cc_r_mastermaster
= cc_r; else cc_r_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 cc_r = 65'bx; else #1 cc_r = cc_r_mastermaster
; end
//
wire [2:0] wcwpm1
= `Mexec.psr_mod.cwp_mod.wcwpm1;
wire [2:0] result_cwp
= `Mexec.psr_mod.cwp_mod.result_cwp;
wire [2:0] d_cwpp1
= `Mexec.psr_mod.cwp_mod.cwpp1;
wire [2:0] d_cwpm1
= `Mexec.psr_mod.cwp_mod.cwpm1;
reg [2:0] e_cwpp1
, w_cwpp1
, e_cwpm1
, w_cwpm1
, cwp_r
;
reg [2:0] ncwp
;
reg e_cwp_dec
, w_cwp_dec
, e_cwp_inc
, w_cwp_inc
;
reg [(3)-1:0] cwpp1_e_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) cwpp1_e_mastermaster
= d_cwpp1; else if (( hold)===1'b1) cwpp1_e_mastermaster
= e_cwpp1; else cwpp1_e_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 e_cwpp1 = 65'bx; else #1 e_cwpp1 = cwpp1_e_mastermaster
; end
reg [(3)-1:0] cwpp1_w_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) cwpp1_w_mastermaster
= e_cwpp1; else if (( hold)===1'b1) cwpp1_w_mastermaster
= w_cwpp1; else cwpp1_w_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 w_cwpp1 = 65'bx; else #1 w_cwpp1 = cwpp1_w_mastermaster
; end
reg [(3)-1:0] cwpm1_e_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) cwpm1_e_mastermaster
= d_cwpm1; else if (( hold)===1'b1) cwpm1_e_mastermaster
= e_cwpm1; else cwpm1_e_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 e_cwpm1 = 65'bx; else #1 e_cwpm1 = cwpm1_e_mastermaster
; end
reg [(3)-1:0] cwpm1_w_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) cwpm1_w_mastermaster
= e_cwpm1; else if (( hold)===1'b1) cwpm1_w_mastermaster
= w_cwpm1; else cwpm1_w_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 w_cwpm1 = 65'bx; else #1 w_cwpm1 = cwpm1_w_mastermaster
; end
wire d_cwp_dec
= `Mdecode.special_reg_control.d_save
& ~w_cycle_trap;
wire d_restore
= `Mdecode.special_reg_control.d_restore
& ~w_cycle_trap;
wire d_rett
= `Mdecode.special_reg_control.d_rett
& ~w_cycle_trap;
wire d_cwp_inc
= (d_restore | d_rett) & ~w_cycle_trap;
reg [(1)-1:0] e_cwp_dec_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) e_cwp_dec_mastermaster
= d_cwp_dec; else if (( hold)===1'b1) e_cwp_dec_mastermaster
= e_cwp_dec; else e_cwp_dec_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 e_cwp_dec = 65'bx; else #1 e_cwp_dec = e_cwp_dec_mastermaster
; end
wire nw_cwp_dec
= e_cwp_dec & ~w_cycle_trap & ~fold_annul_e;
reg [(1)-1:0] w_cwp_dec_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) w_cwp_dec_mastermaster
= nw_cwp_dec; else if (( hold)===1'b1) w_cwp_dec_mastermaster
= w_cwp_dec; else w_cwp_dec_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 w_cwp_dec = 65'bx; else #1 w_cwp_dec = w_cwp_dec_mastermaster
; end
reg [(1)-1:0] e_cwp_inc_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) e_cwp_inc_mastermaster
= d_cwp_inc; else if (( hold)===1'b1) e_cwp_inc_mastermaster
= e_cwp_inc; else e_cwp_inc_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 e_cwp_inc = 65'bx; else #1 e_cwp_inc = e_cwp_inc_mastermaster
; end
wire nw_cwp_inc
= e_cwp_inc & ~w_cycle_trap & ~fold_annul_e;
reg [(1)-1:0] w_cwp_inc_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) w_cwp_inc_mastermaster
= nw_cwp_inc; else if (( hold)===1'b1) w_cwp_inc_mastermaster
= w_cwp_inc; else w_cwp_inc_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 w_cwp_inc = 65'bx; else #1 w_cwp_inc = w_cwp_inc_mastermaster
; end
wire w_cwp_dec_notrap
= w_cwp_dec & ~w_cycle_trap;
wire w_cwp_inc_notrap
= w_cwp_inc & ~w_cycle_trap;
wire w_cwp_hold
= ~w_cycle_trap & ~w_wrpsr & ~w_cwp_inc & ~w_cwp_dec;
always @ (( w_cycle_trap) or ( w_wrpsr) or ( w_cwp_inc_notrap) or ( w_cwp_dec_notrap) or ( w_cwp_hold) or ( wcwpm1) or ( result_cwp) or ( w_cwpp1) or ( w_cwpm1) or ( cwp_r)) case ({ w_cwp_hold, w_cwp_dec_notrap, w_cwp_inc_notrap, w_wrpsr, w_cycle_trap}) 5'b00001: ncwp = wcwpm1; 5'b00010: ncwp = result_cwp; 5'b00100: ncwp = w_cwpp1; 5'b01000: ncwp = w_cwpm1; 5'b10000: ncwp = cwp_r; default: ncwp = 65'hx; endcase
reg [(3)-1:0] cwp_r_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) cwp_r_mastermaster
= ncwp; else if (( hold)===1'b1) cwp_r_mastermaster
= cwp_r; else cwp_r_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 cwp_r = 65'bx; else #1 cwp_r = cwp_r_mastermaster
; end
/*
wire [2:0] er_ncwp = `IU.iuchip.psr_mod.cwp_mod.ncwp;
wire [2:0] er_cwpm_ = `IU.iuchip.psr_mod.cwp_mod.cwpm_;
wire [2:0] er_cwpm = ~er_cwpm_;
REGWIRE [2:0] cwp_d_out, cwp_e_out, cwp_w_mux, cwp_w_out, cwp_r;
wire sel_cwp_d_mux = cwp_inc | cwp_dec;
REGWIRE sel_cwp_w_mux, sel_cwp_e_mux;
MASTER(sel_cwp_e_master,1, sel_cwp_e_mux, sel_cwp_d_mux, clock, hold)
MASTER(sel_cwp_w_master,1, sel_cwp_w_mux, sel_cwp_e_mux, clock, hold)
MUX2(cwp_d_mux,3, cwp_d_out, er_cwpm, er_ncwp, sel_cwp_d_mux)
MASTER(cwp_e_master,3, cwp_e_out, cwp_d_out, clock, hold)
MASTER(cwp_w_master,3, cwp_w_mux, cwp_e_out, clock, hold)
MUX2(cwp_w_mux,3, cwp_w_out, er_ncwp, cwp_w_mux, sel_cwp_w_mux)
MASTER(cwp_r_master,3, cwp_r, cwp_w_out, clock, hold)
*/
wire [31:0] r_psr
= {
4'h0, // IMPLEMENTATION
4'h4, // VERSION
cc_r, // Condition Codes
6'b0, // RESERVED
ec, // Enable Co-processor
ef, // Enable FPU
pil, // Processor Interrupt Level
s, // Supervisor bit
ps, // Previous state bit
et, // Enable traps bit
2'b0, // Unused bits of the CWP
cwp_r // Current Window Pointer
};
wire d_hnop_in_ex
= `Mdecode.hnop_into_ex;
wire d_htrap_in_ex
= `Mdecode.htrap_into_ex;
wire d_nop_trap_in_ex
= d_hnop_in_ex | d_htrap_in_ex;
reg e_nop_trap_in_ex
, w_nop_trap_in_ex
, r_nop_trap_in_ex
;
reg [(1)-1:0] e_nop_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) e_nop_mastermaster
= d_nop_trap_in_ex; else if (( hold)===1'b1) e_nop_mastermaster
= e_nop_trap_in_ex; else e_nop_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 e_nop_trap_in_ex = 65'bx; else #1 e_nop_trap_in_ex = e_nop_mastermaster
; end
wire nw_nop_trap_in_ex
= e_nop_trap_in_ex | fold_annul_e;
reg [(1)-1:0] w_nop_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) w_nop_mastermaster
= nw_nop_trap_in_ex; else if (( hold)===1'b1) w_nop_mastermaster
= w_nop_trap_in_ex; else w_nop_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 w_nop_trap_in_ex = 65'bx; else #1 w_nop_trap_in_ex = w_nop_mastermaster
; end
reg [(1)-1:0] r_nop_mastermaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) r_nop_mastermaster
= w_nop_trap_in_ex; else if (( hold)===1'b1) r_nop_mastermaster
= r_nop_trap_in_ex; else r_nop_mastermaster
= 65'bx; if(( clock) === 1'bx) #1 r_nop_trap_in_ex = 65'bx; else #1 r_nop_trap_in_ex = r_nop_mastermaster
; end
wire inst_comp
=
~(`Mdecode.ir_control.w_help
& w_valid_decode & ~w_nop_trap_in_ex)
& ~`Mdecode.d_trap
;
// & ~`Mdecode.trapr_dae
// & ~`Mdecode.trapr_daer
// & ~`Mdecode.trapr_dmmum
wire result_compare
= inst_comp & ~r_nop_trap_in_ex;
// 1's catcher for using mpsas to check 2 inst instead on 1
reg fold_comp_almost
;
wire fold_comp
;
wire fold_comp_now
=
fold_in_r & ~fold_annul_r & ~r_cycle_trap
;
wire nfold_comp
= ~result_compare & (fold_comp_now | fold_comp_almost)
;
reg [(1)-1:0] fold_comp_regmaster
; always @ (posedge (clock )) begin if ((hold | scan_mode)===1'b0) fold_comp_regmaster
= nfold_comp; else if ((hold | scan_mode)===1'b1) fold_comp_regmaster
= fold_comp_almost; else fold_comp_regmaster
= 65'bx; if((clock) === 1'bx) #1 fold_comp_almost = 65'bx; else #1 fold_comp_almost = fold_comp_regmaster
; end
assign fold_comp = result_compare &
(fold_comp_almost | fold_comp_now)
;
// instructions complete in the R cycle IF there is
// not a data-access-exception trap this cycle,
// or a floating-point exception, or a co-processor exception
// and the decode opcode is not ({9'o010 | 9'o400, 2'b00}).
wire [7:0] w_opop3
= {`Mdecode.ir_control.w_op,
`Mdecode.ir_control.w_op3};
wire [7:0] r_opop3
= {`Mdecode.ir_control.r_op,
`Mdecode.ir_control.r_op3};
wire same_w_r
= w_opop3 == r_opop3;
wire w_help
= `Mdecode.w_hhn[2];
wire inst_complete =
(~same_w_r | (same_w_r & ~w_help))
& ~`Mdecode.d_trap
;
// & ~`Mdecode.trapr_dae
// & ~`Mdecode.trapr_daer
// & ~`Mdecode.trapr_dmmum
// ~`Mdecode.ir_control.r_help
// The PC of this instruction is in the TPC register
// A branch ALWAYS instruction in WRITE with a displacement
// of zero is used at the end of a diagnostic.
// The following logic detects this situation.
wire [3:0] w_cond
; // used to be reg
// must pipeline from W master because of RF_XLATE between master
// and slave in the IR pipe
assign w_cond = `Mdecode.ir.w_rdm[3:0];
// need to pipeline the displacement into the W stage
reg [21:0] e_disp22
;
reg [21:0] w_disp22
;
/*
* Modified for SUNERGY Puma
* Puma registers disp22 from the D cycle (in_dec), not in E.
SLAVE(e_disp_slave,22, e_disp22, `IU.iuchip.disp22, clock)
*
*/
reg [(22)-1:0] e_disp_regmaster
; always @ (posedge ( clock )) begin if (( hold)===1'b0) e_disp_regmaster
= `Mdecode.in_dec[21:0]; else if (( hold)===1'b1) e_disp_regmaster
= e_disp22; else e_disp_regmaster
= 65'bx; if(( clock) === 1'bx) #1 e_disp22 = 65'bx; else #1 e_disp22 = e_disp_regmaster
; end
reg [(22)-1:0] w_disp_regmaster
; always @ (posedge ( clock )) begin if (( hold | scan_mode)===1'b0) w_disp_regmaster
= e_disp22; else if (( hold | scan_mode)===1'b1) w_disp_regmaster
= w_disp22; else w_disp_regmaster
= 65'bx; if(( clock) === 1'bx) #1 w_disp22 = 65'bx; else #1 w_disp22 = w_disp_regmaster
; end
wire end_diagnostic =
`Mdecode.ir_control.w_hop2==6'b0_00_010
& w_cond==4'b1000 & w_disp22==22'b0 &
~scan_mode ;
// synopsys translate_off
// monitor statements to check on i$ multicycle path
// if IU is strobing D$ data, the tristate enable is on, the
// mmu_data_sel = 01 and the I$ data received by the IU is not
// the same for the last two cycles, then the MCP has been violated.
// wire [1:0] mmu_data_sel = Msystem.ssparc.ssparc_mmu.MMU_cache.MMU_cntl.MMU_regs.mmu_data_sel[1:0];
// wire tri32_en = Msystem.ssparc.ssparc_mmu.MMU_cache.MMU_cntl.MMU_regs.tri32_en;
// wire [31:0] cur_ibus = iu.iuchip.Icache_data;
// wire gg_clock = iu.iuchip.decode.ss_clock;
// REGWIRE [31:0] last_ibus;
// REG(last_ibus_reg,32,last_ibus,cur_ibus,gg_clock,1'b0)
// wire stable_for_2 = cur_ibus==last_ibus;
// wire hold_r_reg = iu.iuchip.exec.hold_r_reg;
// always @ (hold_r_reg or stable_for_2 or mmu_data_sel[1] or mmu_data_sel[0] or tri32_en) begin
// if ((hold_r_reg === 1'b0) && (stable_for_2 != 1'b1) &&
// (tri32_en === 1'b1) && (mmu_data_sel === 2'b01)) begin
// $display("*** MCP for I$ ASI read violated");
// Mclocks.error_count = Mclocks.error_count + 1;
// end
// end
// synopsys translate_on
endmodule
module Mtrace
( inst_complete, tpc, end_diagnostic,
clock, hold, scan_mode
);
input inst_complete
; // indicates that an instruction completed this cycle
input [31:2] tpc
; // it's address
input end_diagnostic
; // active when infinite loop branch is seen in W
input clock
;
input hold
;
input scan_mode
;
/*
This module controls instruction tracing. The trace is turned on
by forcing trace=1. It then prints a continuous trace of the
addresses of instructions as they complete.
*/
reg trace
;
// reg [31:0] fd; // file descriptor (moved to Mclocks - JP)
reg trap_handler
;
// Time stamp of last instruction completion
reg [31:0] last_complete
;
// Maximum cycles allowed between instructions before quitting
// Force this to change the value
reg [31:0] cycle_limit
;
// pipeline for 1 cycle, to ensure that the prior instruction
// completes. Save diag error status (annul bit) as well.
reg end_diag
;
reg [(1)-1:0] end_diag_ffmaster
; always @ (posedge ( clock )) begin if (( hold | scan_mode)===1'b0) end_diag_ffmaster
= end_diagnostic; else if (( hold | scan_mode)===1'b1) end_diag_ffmaster
= end_diag; else end_diag_ffmaster
= 65'bx; if(( clock) === 1'bx) #1 end_diag = 65'bx; else #1 end_diag = end_diag_ffmaster
; end
reg end_diag_error
;
/*
* `end_diagnostic' becomes true for the branch-to-self instruction diags use
* to signal completion.
* Use the `annul' bit of the branch-to-self instruction as an error flag.
* This is for diags to signal an error from inside assembly code (for instance,
* when SAS won't run the code).
* Take the flag from bit 29 of the write stage of the pipe (high bit in the
* destination register field) when end_diagnostic (decode of write stage IR)
* is true. Once set, hold it until reset.
*/
wire error_flag
=
(end_diagnostic & `Mdecode.ir.w_rdm[4])
| end_diag_error ;
reg [(1)-1:0] end_diag_err_ffmaster
; always @ (posedge ( clock )) begin if (( hold | scan_mode)===1'b0) end_diag_err_ffmaster
= error_flag; else if (( hold | scan_mode)===1'b1) end_diag_err_ffmaster
= end_diag_error; else end_diag_err_ffmaster
= 65'bx; if(( clock) === 1'bx) #1 end_diag_error = 65'bx; else #1 end_diag_error = end_diag_err_ffmaster
; end
wire [11:0] trap_tt_reg
= {`Mexec.tbr_mod.tbrm[11:4],4'b0};
// This is set starting in the (R+1)-cycle of the terminating branch
// instruction, and stays set forever
reg diag_done
;
reg [(1)-1:0] diag_done_ffmaster
; always @ (posedge ( clock )) begin if (( hold | scan_mode)===1'b0) diag_done_ffmaster
= trace&((end_diag===1)|(diag_done===1)); else if (( hold | scan_mode)===1'b1) diag_done_ffmaster
= diag_done; else diag_done_ffmaster
= 65'bx; if(( clock) === 1'bx) #1 diag_done = 65'bx; else #1 diag_done = diag_done_ffmaster
; end
initial begin
trace = 0;
Mclocks.trace_mcd = 0;
last_complete = 0 ;
// cycle_limit = 500 ;
$GetEnv("cycle_limit",cycle_limit);
end
wire fold_in_e
= `Mdecode.pc_cntl.fold_in_e
& ~(`Mdecode.IU_in_trap);
reg fold_in_w
;
reg [(1)-1:0] fiw_regmaster
; always @ (posedge (clock )) begin if ((hold | scan_mode)===1'b0) fiw_regmaster
= fold_in_e; else if ((hold | scan_mode)===1'b1) fiw_regmaster
= fold_in_w; else fiw_regmaster
= 65'bx; if((clock) === 1'bx) #1 fold_in_w = 65'bx; else #1 fold_in_w = fiw_regmaster
; end
reg fold_in_r
;
reg [(1)-1:0] fir_regmaster
; always @ (posedge (clock )) begin if ((hold | scan_mode)===1'b0) fir_regmaster
= fold_in_w; else if ((hold | scan_mode)===1'b1) fir_regmaster
= fold_in_r; else fir_regmaster
= 65'bx; if((clock) === 1'bx) #1 fold_in_r = 65'bx; else #1 fold_in_r = fir_regmaster
; end
reg fold_postr
;
reg [(1)-1:0] fold_postr_regmaster
; always @ (posedge (clock )) begin if ((hold | scan_mode)===1'b0) fold_postr_regmaster
= fold_in_r; else if ((hold | scan_mode)===1'b1) fold_postr_regmaster
= fold_postr; else fold_postr_regmaster
= 65'bx; if((clock) === 1'bx) #1 fold_postr = 65'bx; else #1 fold_postr = fold_postr_regmaster
; end
wire fold_annul_e
= `Mdecode.pc_cntl.fold_annul
& ~(`Mdecode.TRAP);
reg fold_annul_w
;
reg [(1)-1:0] faw_regmaster
; always @ (posedge (clock )) begin if ((hold | scan_mode)===1'b0) faw_regmaster
= fold_annul_e; else if ((hold | scan_mode)===1'b1) faw_regmaster
= fold_annul_w; else faw_regmaster
= 65'bx; if((clock) === 1'bx) #1 fold_annul_w = 65'bx; else #1 fold_annul_w = faw_regmaster
; end
reg fold_annul_r
;
reg [(1)-1:0] far_regmaster
; always @ (posedge (clock )) begin if ((hold | scan_mode)===1'b0) far_regmaster
= fold_annul_w; else if ((hold | scan_mode)===1'b1) far_regmaster
= fold_annul_r; else far_regmaster
= 65'bx; if((clock) === 1'bx) #1 fold_annul_r = 65'bx; else #1 fold_annul_r = far_regmaster
; end
reg fold_annul_pr
;
reg [(1)-1:0] fapr_regmaster
; always @ (posedge (clock )) begin if ((hold | scan_mode)===1'b0) fapr_regmaster
= fold_annul_r; else if ((hold | scan_mode)===1'b1) fapr_regmaster
= fold_annul_pr; else fapr_regmaster
= 65'bx; if((clock) === 1'bx) #1 fold_annul_pr = 65'bx; else #1 fold_annul_pr = fapr_regmaster
; end
reg [31:2] pc
;
reg [(30)-1:0] pc_regmaster
; always @ (posedge ( clock )) begin if (( hold | scan_mode)===1'b0) pc_regmaster
= tpc; else if (( hold | scan_mode)===1'b1) pc_regmaster
= pc; else pc_regmaster
= 65'bx; if(( clock) === 1'bx) #1 pc = 65'bx; else #1 pc = pc_regmaster
; end
reg [31:2] pcl
;
wire [31:2] npcl
= tpc - ({29'b0, 1'b1});
reg [(30)-1:0] pcl_regmaster
; always @ (posedge (clock )) begin if (( hold | scan_mode)===1'b0) pcl_regmaster
= npcl; else if (( hold | scan_mode)===1'b1) pcl_regmaster
= pcl; else pcl_regmaster
= 65'bx; if((clock) === 1'bx) #1 pcl = 65'bx; else #1 pcl = pcl_regmaster
; end
reg maybe_complete
;
reg [(1)-1:0] complete_ffmaster
; always @ (posedge ( clock )) begin if (( hold | scan_mode)===1'b0) complete_ffmaster
= inst_complete; else if (( hold | scan_mode)===1'b1) complete_ffmaster
= maybe_complete; else complete_ffmaster
= 65'bx; if(( clock) === 1'bx) #1 maybe_complete = 65'bx; else #1 maybe_complete = complete_ffmaster
; end
/* cancel completion when R cycle contains a help
and an R cycle trap is occuring. This case can occur
for data access exceptions on the 2nd access of a 9'o303 */
wire same_w_r
= Mtask.complete.same_w_r;
wire w_help
= `Mdecode.w_hhn[2];
wire r_help
= `Mdecode.ir_control.r_help;
wire complete
= maybe_complete
& ~( (~same_w_r | (same_w_r & ~w_help))
& (`Mdecode.TRAP & r_help) );
// & ~( `Mdecode.ir_control.r_help
// & `Mdecode.TRAP );
// & ( `Mdecode.trapr_dae
// | `Mdecode.trapr_daer
// | `Mdecode.trapr_dmmum
// ));
wire fold_del_trap_w
= fold_in_w & `Mdecode.TRAP;
reg fold_del_trap_r
;
reg [(1)-1:0] fdt_r_regmaster
; always @ (posedge (clock )) begin if ((hold | scan_mode)===1'b0) fdt_r_regmaster
= fold_del_trap_w; else if ((hold | scan_mode)===1'b1) fdt_r_regmaster
= fold_del_trap_r; else fdt_r_regmaster
= 65'bx; if((clock) === 1'bx) #1 fold_del_trap_r = 65'bx; else #1 fold_del_trap_r = fdt_r_regmaster
; end
reg fold_del_trap_pr
;
reg [(1)-1:0] fdt_pr_regmaster
; always @ (posedge (clock )) begin if ((hold | scan_mode)===1'b0) fdt_pr_regmaster
= fold_del_trap_r; else if ((hold | scan_mode)===1'b1) fdt_pr_regmaster
= fold_del_trap_pr; else fdt_pr_regmaster
= 65'bx; if((clock) === 1'bx) #1 fold_del_trap_pr = 65'bx; else #1 fold_del_trap_pr = fdt_pr_regmaster
; end
wire [10:0] r_opcode
=
`Mdecode.ir_control.r_opcode;
wire r_op_hnop
= r_opcode==({9'o000 | 9'o400, 2'b00});
wire r_op_htrap
= r_opcode==({9'o010 | 9'o400, 2'b00});
wire nwrite_trace
=
~hold & ~r_op_hnop & ~r_op_htrap
& (complete | fold_del_trap_pr)
& ~scan_mode;
reg write_trace
;
reg [(1)-1:0] write_trace_regmaster
; always @ (posedge (clock )) begin if ((scan_mode)===1'b0) write_trace_regmaster
= nwrite_trace; else if ((scan_mode)===1'b1) write_trace_regmaster
= write_trace; else write_trace_regmaster
= 65'bx; if((clock) === 1'bx) #1 write_trace = 65'bx; else #1 write_trace = write_trace_regmaster
; end
wire ic_miss
= `rl_ic_cntl.ic_miss_or_part |
(~`rl_ic_cntl.it_hit_f & `rl_ic_cntl.ic_miss_and_part);
wire dc_miss
= `rl_dc_cntl.dc_miss_or_part |
(~`rl_dc_cntl.dt_hit_w & `rl_dc_cntl.dc_miss_and_part);
wire wb_empty
= ~(`rl_dc_cntl.wb_valid[1] | `rl_dc_cntl.wb_valid[0]);
always @ (negedge clock) begin : Trace
if (~trace) begin
// Update last_complete in case someone turns on trace
last_complete = Mclocks.cycle_count ;
if(Mclocks.trace_mcd != 0) begin
$fclose(Mclocks.trace_mcd);
Mclocks.trace_mcd = 0;
end
end
else if (diag_done !== 1'b1) begin
if(Mclocks.trace_mcd == 0) begin
Mclocks.trace_mcd =
$fopen({Mclocks.working_dir,"/trace.v"});
if(Mclocks.trace_mcd==0) begin
$display("*** couldn't open `trace.v' for writing");
disable Trace;
end
end
if(write_trace) begin
trap_handler = 0;
if(
({pc,2'b00} & 32'hfffffff0)=='h10
|({pc,2'b00} & 32'hfffffff0)=='h90
|({pc,2'b00} & 32'hfffffff0)=='h110
|({pc,2'b00} & 32'hfffffff0)=='h120
|({pc,2'b00} & 32'hfffffff0)=='h130
|({pc,2'b00} & 32'hfffffff0)=='h140
|({pc,2'b00} & 32'hfffffff0)=='h150
|({pc,2'b00} & 32'hfffffff0)=='h160
|({pc,2'b00} & 32'hfffffff0)=='h170
|({pc,2'b00} & 32'hfffffff0)=='h180
|({pc,2'b00} & 32'hfffffff0)=='h190
|({pc,2'b00} & 32'hfffffff0)=='h1a0
|({pc,2'b00} & 32'hfffffff0)=='h1b0
|({pc,2'b00} & 32'hfffffff0)=='h1c0
|({pc,2'b00} & 32'hfffffff0)=='h1d0
|({pc,2'b00} & 32'hfffffff0)=='h1e0
|({pc,2'b00} & 32'hfffffff0)=='h210
|({pc,2'b00} & 32'hfffffff0)=='h200
|({pc,2'b00} & 32'hfffffff0)=='h290
) trap_handler = 1;
/*************************************************/
/* */
/* if not a trap handler, or we're tracing traps */
/* then dump the pc into the trace file. If I-I */
/* compare, then print out the correct message */
/* */
/*************************************************/
if ((!trap_handler) |
(trap_handler & Mtask.trace_trap_handlers))
begin
if (!fold_postr) begin
$fdisplay(Mclocks.trace_mcd, "0x%0h", {pc,2'b00});
end
if (fold_postr) begin
if (fold_annul_pr | fold_del_trap_pr) begin
$fdisplay(Mclocks.trace_mcd, "0x%0h", {pcl,2'b00});
end
if (!fold_annul_pr & !fold_del_trap_pr) begin
$fdisplay(Mclocks.trace_mcd, "0x%0h", {pcl,2'b00});
$fdisplay(Mclocks.trace_mcd, "0x%0h", {pc,2'b00});
end
end
// Don't print message if I-I sas is running
if (!sastasks.Im_here) begin
if (fold_postr) begin
$display;
$fwrite(Mccdisp.allvec_mcd, "// ") ;
$fwrite(Mccdisp.allvec_tto_mcd,
"FOLD 0x%x in cycle %d ",
{pcl,2'b00}, Mclocks.cycle_count);
end
$display;
$fwrite(Mccdisp.allvec_mcd, "// ") ;
$fwrite(Mccdisp.allvec_tto_mcd,
"COMPLETED 0x%x in cycle %d ",
{pc,2'b00}, Mclocks.cycle_count);
$fdisplay(Mccdisp.allvec_mcd) ;
end
end
else begin
// Don't print message if I-I sas is running
if (!sastasks.Im_here) begin
$display;
$fwrite(Mccdisp.allvec_mcd, "// ") ;
$fwrite(Mccdisp.allvec_tto_mcd,
"COMPLETED 0x%x in cycle %d UNTRACED ",
{pc,2'b00}, Mclocks.cycle_count);
$fdisplay(Mccdisp.allvec_mcd) ;
end
end
last_complete = Mclocks.cycle_count ;
end
// prevent hang detection when scan_mode is active
else if(scan_mode)
last_complete = Mclocks.cycle_count ;
// prevent hang detection at rerun
This page: |
Created: | Thu Aug 19 12:00:46 1999 |
| From: |
../../../sparc_v8/env/rtl/iutrace.vpp
|