/******************************************************************************/
/* */
/* 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: @(#)pc.v
***
***
****************************************************************************
****************************************************************************/
// @(#)pc.v 1.46 4/7/93
// pc.v
//-----------------------------------------------------------------------------
// PC's
/*
The following module describes the datapath of the PC section.
It includes the cache address registers (ICAR), PC's (DPC, EPC, WPC,
TPC), the address adder, address incrementer
*/
module Mpc
(
tpc, wpc, iu_epc, fpc,
fpc_low, nlta_low, ndpc_low, last_gen,
alu_shift_hi30,
tbrm,
sadr_tbr,
sadr_jmprett, sadr_zero,
fold_aa,
sel_last_gen, recirc2_default, sel_inc_ll_gen,
sel_inc_dpc, sel_inc_alttag,
sel_gpc, sel_recirc, sel_recirc_inc,
sel_lgen_iva,
sel_gpc_ic, sel_recirc_ic, sel_recirc_inc_ic,
sadr_zero_ic, force_ifill, force_dva,
sel_lgen_ica,
imiss_in_progress,
i_nfillp,
sel_lta_fpc, sel_idpc_fpc, sel_post_reset,
sel_p_fpc, sel_alt_tag, sel_i1pfpc_fpc, sel_i2dpc_fpc,
alt_tag,
hld_dpc,
hld_car_mar, hld_lgens,
iu_iva_g, icache_adr, icache_tag_in,
fwd_wpc, use_tpc, fwd_tpcm4,
ss_clock, hold, lta_hold, hold_ic,
reset, start_itag_inv,
ss_scan_mode,
// input_clock_l, input_clock_buf, 6-5-96
pc_scan_in,
pc_scan_out
);
// DATA
//output [31:2] car; // Cache Address.
output [31:2] tpc
; // Trap PC register
output [31:2] wpc
; // Write PC register
output [31:2] iu_epc
; // Decode PC
output [31:2] fpc
;
output fpc_low
;
output nlta_low
;
output ndpc_low
;
output [31:2] last_gen
;
//input [29:0] in_dec_lo30; // instruction in decode.
input [31:2] alu_shift_hi30
; // ALU source for jmp and rett.
input [31:4] tbrm
; // trap base register.
// CONTROL
input sadr_tbr
; // select TBR as next address
input sadr_jmprett
; // select address from jmpl, rett
input sadr_zero
; // select 0 address
//input sadr_fold_aa;
input [31:2] fold_aa
;
input sel_last_gen
, recirc2_default
, sel_inc_ll_gen
;
input sel_inc_dpc
, sel_inc_alttag
;
input sel_gpc
, sel_recirc
, sel_recirc_inc
;
input sel_lgen_iva
;
input sel_gpc_ic
, sel_recirc_ic
, sel_recirc_inc_ic
;
input sadr_zero_ic
, force_ifill
, force_dva
;
input sel_lgen_ica
;
input imiss_in_progress
;
input [4:3] i_nfillp
;
input sel_lta_fpc
, sel_idpc_fpc
, sel_post_reset
;
input sel_p_fpc
, sel_alt_tag
, sel_i1pfpc_fpc
, sel_i2dpc_fpc
;
input [31:2] alt_tag
;
//input [11:2] low_D_cache_adr; // for muxing onto I$ adr bus
input hld_dpc
; // hold value of DPC
//input rtrap_hldpc; // hold PC chain on R cycle traps
//input cheat_pcfwd; // cheat and move PC's around in case of
// jmp and iacc trap in its delay slot
input hld_car_mar
; // hold value of CAR
input hld_lgens
;
//input hld_mar; // hold value of MAR
output [31:2] iu_iva_g
; // I cache address to ICC
output [13:3] icache_adr
; // I cache addr direct to SRAMs
output [31:14] icache_tag_in
; // I cache addr for tag compare
input fwd_wpc
, use_tpc
, fwd_tpcm4
;
// MISC
input ss_clock
; // primary clock
input hold
; // over-riding hold
input lta_hold
;
input hold_ic
;
input reset
; // chip reset
input start_itag_inv
; // from ic to invalidate tag of perr
input ss_scan_mode
;
// input input_clock_l; 6-5-96
// output input_clock_buf; 6-5-96
input pc_scan_in
;
output pc_scan_out
;
wire [31:2] car
;
wire [31:2] mar
;
wire [31:2] dpc
; // dpc
wire [31:2] last_gen;
wire [31:2] ll_gen
;
/*
These mux selects are buffered with a special cell that
turns the select off with ss_scan_mode. some are turned
on with ss_scan_mode - this stuff buffers the signal
in the DP and guarantees that only 1 select is on at a
time during scan (in conjunction with the control logic)
*/
// nadr_sel_mux doesn't need any. taken care of in Mdecode
// for recirc2_mux
wire recirc2_default_sm
= recirc2_default | ss_scan_mode;
wire sel_inc_ll_gen_sm
= sel_inc_ll_gen & ~ss_scan_mode;
wire sel_inc_dpc_sm
= sel_inc_dpc & ~ss_scan_mode;
wire sel_inc_alttag_sm
= sel_inc_alttag & ~ss_scan_mode;
// for gen_addr_mux
wire sel_gpc_sm
= sel_gpc & ~ss_scan_mode;
wire sel_recirc_sm
= sel_recirc & ~ss_scan_mode;
wire sel_recirc_inc_sm
= sel_recirc_inc & ~ss_scan_mode;
wire sel_lgen_iva_sm
= sel_lgen_iva & ~ss_scan_mode;
wire sadr_zero_sm
= sadr_zero | ss_scan_mode;
// for icache_adr_mux
wire sel_gpc_ic_sm
= sel_gpc_ic & ~ss_scan_mode;
wire sel_recirc_ic_sm
= sel_recirc_ic & ~ss_scan_mode;
wire sel_recirc_inc_ic_sm
= sel_recirc_inc_ic & ~ss_scan_mode;
wire sadr_zero_ic_sm
= sadr_zero_ic | ss_scan_mode;
wire force_dva_sm
= force_dva & ~ss_scan_mode;
wire force_ifill_sm
= force_ifill & ~ss_scan_mode;
wire sel_lgen_ica_sm
= sel_lgen_ica & ~ss_scan_mode;
// for fpc_mux
wire sel_lta_fpc_sm
= sel_lta_fpc & ~ss_scan_mode;
wire sel_idpc_fpc_sm
= sel_idpc_fpc & ~ss_scan_mode;
wire sel_post_reset_sm
= sel_post_reset | ss_scan_mode;
wire sel_p_fpc_sm
= sel_p_fpc & ~ss_scan_mode;
wire sel_alt_tag_sm
= sel_alt_tag & ~ss_scan_mode;
wire sel_i1pfpc_fpc_sm
= sel_i1pfpc_fpc & ~ss_scan_mode;
wire sel_i2dpc_fpc_sm
= sel_i2dpc_fpc & ~ss_scan_mode;
// for tpc_mux
wire fwd_wpc_sm
= fwd_wpc & ~ss_scan_mode;
wire use_tpc_sm
= use_tpc | ss_scan_mode;
wire fwd_tpcm4_sm
= fwd_tpcm4 & ~ss_scan_mode;
// this inverter is used to buffer the PLL output for the
// clock controller. it is already inverted by Mqueue.
// wire input_clock_buf = ~input_clock_l; 6-5-96
// these signals belong in the SPR slice
// if the last fill write to the I$ got a parity error, hold
// the fill address for the I$. can tell if it is the last
// because imiss_in_progress will be off. this also works for
// non-cached parity errors - imiss_in_progress is always on for
// that case.
wire hld_filladdr
= imiss_in_progress | start_itag_inv;
wire gpcadr_default
= ~sadr_tbr & ~sadr_jmprett;
wire sel_last_gen_l
= ~sel_last_gen;
// these hold signals also belong in the SPR slice
wire hld_lgens_real
= hld_lgens | hold;
wire lta_hold_real
= lta_hold | hold;
wire hld_car_mar_real
= hld_car_mar | hold_ic;
// NEXT ADDRESS MUX
wire [31:2] iu_iva_g;
wire [31:2] gpc_adr
;
wire [31:2] tbr_upper
= {tbrm[31:4], 2'b0}; // simplify mux argument
wire [31:2] zeros_30
= 30'b0; // simplify mux argument
// Expanded macro begin.
// cmux3d(nadr_sel_mux, 30, gpc_adr, alu_shift_hi30[31:2], sadr_jmprett, tbr_upper, sadr_tbr, fold_aa, gpcadr_default)
function [30:1] nadr_sel_mux ;
input [30:1] in0_fn ;
input s0_fn ;
input [30:1] in1_fn ;
input s1_fn ;
input [30:1] in2_fn ;
input s2_fn ;
reg [30:1] out_fn ;
begin
case ({ gpcadr_default, sadr_tbr, sadr_jmprett}) /* 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
nadr_sel_mux = out_fn ;
end
endfunction
assign gpc_adr = nadr_sel_mux( alu_shift_hi30[31:2], sadr_jmprett, tbr_upper, sadr_tbr, fold_aa, gpcadr_default) ;
// synopsys translate_off
always @ (posedge(~Mclocks.clock))
#1 if (( gpcadr_default+ sadr_tbr+ sadr_jmprett !== 1) & `SS_SCOPE.input_reset_l &
~Mtask.trace.ppr & ~( gpcadr_default+ sadr_tbr^ sadr_jmprett===1'bx)) begin
$display("### %m.nadr_sel_mux: CMUX3D select error!\n");
$display(" gpcadr_default, sadr_tbr, sadr_jmprett=%0d%0d%0d\n", gpcadr_default, sadr_tbr, sadr_jmprett);
Mclocks.warning_count = Mclocks.warning_count + 1;
end
// synopsys translate_on
// Expanded macro end.
//this selest was sadr_fold_aa
// aa_out, sadr_aa_inv,// adr_plus, sadr_inc_inv,
// zeros_30, sadr_zero_sm,
wire [31:2] recirc1
;
// Expanded macro begin.
// cmux2d(recirc1_mux, 30, recirc1, last_gen, sel_last_gen, ll_gen, sel_last_gen_l)
function [30:1] recirc1_mux ;
input [30:1] in0_fn ;
input s0_fn ;
input [30:1] in1_fn ;
input s1_fn ;
reg [30:1] out_fn ;
begin
case ({ sel_last_gen_l, sel_last_gen}) /* synopsys parallel_case */
2'b01: out_fn = in0_fn;
2'b10: out_fn = in1_fn;
default: out_fn = 65'hx;
endcase
recirc1_mux = out_fn ;
end
endfunction
assign recirc1 = recirc1_mux( last_gen, sel_last_gen, ll_gen, sel_last_gen_l) ;
// synopsys translate_off
always @ (posedge(~Mclocks.clock))
#1 if (( sel_last_gen_l+ sel_last_gen !== 1) & `SS_SCOPE.input_reset_l &
~Mtask.trace.ppr & ~( sel_last_gen_l^ sel_last_gen===1'bx)) begin
$display("### %m.recirc1_mux: CMUX2D select error!\n");
$display(" sel_last_gen_l, sel_last_gen=%0d%0d\n", sel_last_gen_l, sel_last_gen);
Mclocks.warning_count = Mclocks.warning_count + 1;
end
// synopsys translate_on
// Expanded macro end.
// this select was sel_ll_gen
wire dum1
= 1'b0; // all this garbage since this is inc2
wire dum0
;
wire [31:2] inc_last_gen
;
Fincr_30 inc30_ilg({dum0,inc_last_gen[31:3]}, {dum1,last_gen[31:3]});
assign inc_last_gen[2] = last_gen[2];
wire dum2
;
wire [31:2] inc_ll_gen
;
Fincr_30 inc30_illg({dum2,inc_ll_gen[31:3]}, {dum1,ll_gen[31:3]});
assign inc_ll_gen[2] = ll_gen[2];
wire [31:2] inc_dpc
;
Fincr_30 inc30_id(inc_dpc, dpc);
wire [31:2] int_alttag
;
Fincr_30 inc30_iat(int_alttag, alt_tag);
wire [31:2] recirc2
;
// Expanded macro begin.
// cmux4d(recirc2_mux, 30, recirc2, ({inc_last_gen[31:3],1'b0}), recirc2_default_sm, ({inc_ll_gen[31:3],1'b0}), sel_inc_ll_gen_sm, ({inc_dpc[31:3],1'b0}), sel_inc_dpc_sm, ({int_alttag[31:3],1'b0}), sel_inc_alttag_sm)
function [30:1] recirc2_mux ;
input [30:1] in0_fn ;
input s0_fn ;
input [30:1] in1_fn ;
input s1_fn ;
input [30:1] in2_fn ;
input s2_fn ;
input [30:1] in3_fn ;
input s3_fn ;
reg [30:1] out_fn ;
begin
case ({ sel_inc_alttag_sm, sel_inc_dpc_sm, sel_inc_ll_gen_sm, recirc2_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
recirc2_mux = out_fn ;
end
endfunction
assign recirc2 = recirc2_mux( ({inc_last_gen[31:3],1'b0}), recirc2_default_sm, ({inc_ll_gen[31:3],1'b0}), sel_inc_ll_gen_sm, ({inc_dpc[31:3],1'b0}), sel_inc_dpc_sm, ({int_alttag[31:3],1'b0}), sel_inc_alttag_sm) ;
// synopsys translate_off
always @ (posedge(~Mclocks.clock))
#1 if (( sel_inc_alttag_sm+ sel_inc_dpc_sm+ sel_inc_ll_gen_sm+ recirc2_default_sm !== 1) & `SS_SCOPE.input_reset_l &
~Mtask.trace.ppr & ~( sel_inc_alttag_sm+ sel_inc_dpc_sm+ sel_inc_ll_gen_sm^ recirc2_default_sm===1'bx)) begin
$display("### %m.recirc2_mux: CMUX4D select error!\n");
$display(" sel_inc_alttag_sm, sel_inc_dpc_sm, sel_inc_ll_gen_sm, recirc2_default_sm=%0d%0d%0d%0d\n", sel_inc_alttag_sm, sel_inc_dpc_sm, sel_inc_ll_gen_sm, recirc2_default_sm);
Mclocks.warning_count = Mclocks.warning_count + 1;
end
// synopsys translate_on
// Expanded macro end.
// mux select for inc_last_gen was sel_inc_last_gen
// Expanded macro begin.
// cmux5d(gen_addr_mux, 30, iu_iva_g, ({gpc_adr[31:3],1'b0}), sel_gpc_sm, recirc1, sel_recirc_sm, recirc2, sel_recirc_inc_sm, car, sel_lgen_iva_sm, zeros_30, sadr_zero_sm)
function [30:1] gen_addr_mux ;
input [30:1] in0_fn ;
input s0_fn ;
input [30:1] in1_fn ;
input s1_fn ;
input [30:1] in2_fn ;
input s2_fn ;
input [30:1] in3_fn ;
input s3_fn ;
input [30:1] in4_fn ;
input s4_fn ;
reg [30:1] out_fn ;
begin
case ({ sadr_zero_sm, sel_lgen_iva_sm, sel_recirc_inc_sm, sel_recirc_sm, sel_gpc_sm}) /* synopsys parallel_case */
5'b00001: out_fn = in0_fn ;
5'b00010: out_fn = in1_fn ;
5'b00100: out_fn = in2_fn ;
5'b01000: out_fn = in3_fn ;
5'b10000: out_fn = in4_fn ;
default: out_fn = 65'hx;
endcase
gen_addr_mux = out_fn ;
end
endfunction
assign iu_iva_g = gen_addr_mux( ({gpc_adr[31:3],1'b0}), sel_gpc_sm, recirc1, sel_recirc_sm, recirc2, sel_recirc_inc_sm, car, sel_lgen_iva_sm, zeros_30, sadr_zero_sm) ;
// synopsys translate_off
always @ (posedge(~Mclocks.clock))
#1 if (( sadr_zero_sm+ sel_lgen_iva_sm+ sel_recirc_inc_sm+ sel_recirc_sm+ sel_gpc_sm !== 1) & `SS_SCOPE.input_reset_l &
~Mtask.trace.ppr & ~( sadr_zero_sm+ sel_lgen_iva_sm+ sel_recirc_inc_sm+ sel_recirc_sm^ sel_gpc_sm===1'bx)) begin
$display("### %m.gen_addr_mux: CMUX5D select error!\n");
$display(" sadr_zero_sm, sel_lgen_iva_sm, sel_recirc_inc_sm, sel_recirc_sm, sel_gpc_sm=%0d%0d%0d%0d%0d\n", sadr_zero_sm, sel_lgen_iva_sm, sel_recirc_inc_sm, sel_recirc_sm, sel_gpc_sm);
Mclocks.warning_count = Mclocks.warning_count + 1;
end
// synopsys translate_on
// Expanded macro end.
// ({alu_shift_hi30[31:3],1'b0}), force_dva,
// icache_adr mux's
wire [13:3] icache_adr;
wire [13:3] iva_f
;
Mflipflop_11 iva_f_reg_11(iva_f,iu_iva_g[13:3],ss_clock,1'b0) ; // ,hold)
wire [13:3] fill_adr
;
Mflipflop_9 fill_adr_hi_reg_9(fill_adr[13:5],iva_f[13:5],ss_clock, hld_filladdr) ;
wire [4:3] nfill_adr_low
;
// Expanded macro begin.
// cmux2(nfill_adr_low_mux, 2, nfill_adr_low, iva_f[4:3], i_nfillp, imiss_in_progress)
function [2:1] nfill_adr_low_mux ;
input [2:1] in0_fn ;
input [2:1] in1_fn ;
input select_fn ;
reg [2: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
nfill_adr_low_mux = out_fn ;
end
endfunction
assign nfill_adr_low = nfill_adr_low_mux( iva_f[4:3], i_nfillp, imiss_in_progress) ;
// Expanded macro end.
Mflipflop_2 fill_adr_low_reg_2(fill_adr[4:3],nfill_adr_low,ss_clock,1'b0) ;
// Expanded macro begin.
// cmux7d(icache_adr_mux, 11, icache_adr, gpc_adr[13:3], sel_gpc_ic_sm, recirc1[13:3], sel_recirc_ic_sm, recirc2[13:3], sel_recirc_inc_ic_sm, zeros_30[13:3], sadr_zero_ic_sm, alu_shift_hi30[13:3], force_dva_sm, fill_adr, force_ifill_sm, car[13:3], sel_lgen_ica_sm)
function [11:1] icache_adr_mux ;
input [11:1] in0_fn ;
input s0_fn ;
input [11:1] in1_fn ;
input s1_fn ;
input [11:1] in2_fn ;
input s2_fn ;
input [11:1] in3_fn ;
input s3_fn ;
input [11:1] in4_fn ;
input s4_fn ;
input [11:1] in5_fn ;
input s5_fn ;
input [11:1] in6_fn ;
input s6_fn ;
reg [11:1] out_fn ;
begin
case ({sel_lgen_ica_sm, force_ifill_sm, force_dva_sm, sadr_zero_ic_sm, sel_recirc_inc_ic_sm, sel_recirc_ic_sm, sel_gpc_ic_sm}) /* synopsys parallel_case */
7'b0000001: out_fn = in0_fn ;
7'b0000010: out_fn = in1_fn ;
7'b0000100: out_fn = in2_fn ;
7'b0001000: out_fn = in3_fn ;
7'b0010000: out_fn = in4_fn ;
7'b0100000: out_fn = in5_fn ;
7'b1000000: out_fn = in6_fn ;
default: out_fn = 65'hx;
endcase
icache_adr_mux = out_fn ;
end
endfunction
assign icache_adr = icache_adr_mux( gpc_adr[13:3], sel_gpc_ic_sm, recirc1[13:3], sel_recirc_ic_sm, recirc2[13:3], sel_recirc_inc_ic_sm, zeros_30[13:3],
sadr_zero_ic_sm, alu_shift_hi30[13:3], force_dva_sm, fill_adr, force_ifill_sm, car[13:3], sel_lgen_ica_sm) ;
// synopsys translate_off
always @ (posedge(~Mclocks.clock))
#1 if ((sel_lgen_ica_sm+ force_ifill_sm+ force_dva_sm+ sadr_zero_ic_sm+ sel_recirc_inc_ic_sm+ sel_recirc_ic_sm+ sel_gpc_ic_sm !== 1) & `SS_SCOPE.input_reset_l &
~Mtask.trace.ppr & ~(sel_lgen_ica_sm+ force_ifill_sm+ force_dva_sm+ sadr_zero_ic_sm+ sel_recirc_inc_ic_sm+ sel_recirc_ic_sm^ sel_gpc_ic_sm===1'bx)) begin
$display("### %m.icache_adr_mux: CMUX7D select error!\n");
$display("sel_lgen_ica_sm, force_ifill_sm, force_dva_sm, sadr_zero_ic_sm, sel_recirc_inc_ic_sm, sel_recirc_ic_sm, sel_gpc_ic_sm=%0d%0d%0d%0d%0d%0d%0d\n", sel_lgen_ica_sm, force_ifill_sm, force_dva_sm, sadr_zero_ic_sm, sel_recirc_inc_ic_sm, sel_recirc_ic_sm, sel_gpc_ic_sm);
Mclocks.warning_count = Mclocks.warning_count + 1;
end
// synopsys translate_on
// Expanded macro end.
// icache tag inputs
wire [31:14] icache_tag_in;
// Expanded macro begin.
// cmux2(icache_tag_in_mux, 18, icache_tag_in, iu_iva_g[31:14], alu_shift_hi30[31:14], force_dva)
function [18:1] icache_tag_in_mux ;
input [18:1] in0_fn ;
input [18:1] in1_fn ;
input select_fn ;
reg [18: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
icache_tag_in_mux = out_fn ;
end
endfunction
assign icache_tag_in = icache_tag_in_mux( iu_iva_g[31:14], alu_shift_hi30[31:14], force_dva) ;
// Expanded macro end.
// CAR (CACHE ADDRESS REGISTER)
wire [31:2] car_muxout
;
Mflipflop_30 car_register_30( car, iu_iva_g, ss_clock, hld_car_mar_real) ;
Mflipflop_30 last_gen_reg_30(last_gen,iu_iva_g,ss_clock,hld_lgens_real) ;
// MAR (MISS ADDRESS REGISTER)
Mflipflop_30 ll_gen_reg_30(ll_gen,last_gen,ss_clock,hld_lgens_real) ;
/*
* FPC determination
*/
wire [31:2] fpc;
wire nlta_low = gpc_adr[2];
wire [31:2] last_targ_adr
;
Mflipflop_30 lta_reg_30(last_targ_adr,gpc_adr,ss_clock,lta_hold_real) ;
wire [31:2] p_fpc
;
wire dum3
= 1'b0;
wire dum4
;
wire [31:2] inc2_dpc
;
Fincr_30 inc30_ic2d({dum4,inc2_dpc[31:3]}, {dum3,dpc[31:3]});
assign inc2_dpc[2] = dpc[2];
wire [31:2] inc1_pfpc
;
Fincr_30 inc30_icpf(inc1_pfpc, p_fpc);
// Expanded macro begin.
// cmux7d(fpc_mux, 30, fpc, last_targ_adr, sel_lta_fpc_sm, inc_dpc, sel_idpc_fpc_sm, 30'b0, sel_post_reset_sm, p_fpc, sel_p_fpc_sm, alt_tag, sel_alt_tag_sm, inc1_pfpc, sel_i1pfpc_fpc_sm, inc2_dpc, sel_i2dpc_fpc_sm)
function [30:1] fpc_mux ;
input [30:1] in0_fn ;
input s0_fn ;
input [30:1] in1_fn ;
input s1_fn ;
input [30:1] in2_fn ;
input s2_fn ;
input [30:1] in3_fn ;
input s3_fn ;
input [30:1] in4_fn ;
input s4_fn ;
input [30:1] in5_fn ;
input s5_fn ;
input [30:1] in6_fn ;
input s6_fn ;
reg [30:1] out_fn ;
begin
case ({ sel_i2dpc_fpc_sm, sel_i1pfpc_fpc_sm, sel_alt_tag_sm, sel_p_fpc_sm, sel_post_reset_sm, sel_idpc_fpc_sm, sel_lta_fpc_sm}) /* synopsys parallel_case */
7'b0000001: out_fn = in0_fn ;
7'b0000010: out_fn = in1_fn ;
7'b0000100: out_fn = in2_fn ;
7'b0001000: out_fn = in3_fn ;
7'b0010000: out_fn = in4_fn ;
7'b0100000: out_fn = in5_fn ;
7'b1000000: out_fn = in6_fn ;
default: out_fn = 65'hx;
endcase
fpc_mux = out_fn ;
end
endfunction
assign fpc = fpc_mux( last_targ_adr, sel_lta_fpc_sm, inc_dpc, sel_idpc_fpc_sm, 30'b0, sel_post_reset_sm, p_fpc,
sel_p_fpc_sm, alt_tag, sel_alt_tag_sm, inc1_pfpc, sel_i1pfpc_fpc_sm, inc2_dpc, sel_i2dpc_fpc_sm) ;
// synopsys translate_off
always @ (posedge(~Mclocks.clock))
#1 if (( sel_i2dpc_fpc_sm+ sel_i1pfpc_fpc_sm+ sel_alt_tag_sm+ sel_p_fpc_sm+ sel_post_reset_sm+ sel_idpc_fpc_sm+ sel_lta_fpc_sm !== 1) & `SS_SCOPE.input_reset_l &
~Mtask.trace.ppr & ~( sel_i2dpc_fpc_sm+ sel_i1pfpc_fpc_sm+ sel_alt_tag_sm+ sel_p_fpc_sm+ sel_post_reset_sm+ sel_idpc_fpc_sm^ sel_lta_fpc_sm===1'bx)) begin
$display("### %m.fpc_mux: CMUX7D select error!\n");
$display(" sel_i2dpc_fpc_sm, sel_i1pfpc_fpc_sm, sel_alt_tag_sm, sel_p_fpc_sm, sel_post_reset_sm, sel_idpc_fpc_sm, sel_lta_fpc_sm=%0d%0d%0d%0d%0d%0d%0d\n", sel_i2dpc_fpc_sm, sel_i1pfpc_fpc_sm, sel_alt_tag_sm, sel_p_fpc_sm, sel_post_reset_sm, sel_idpc_fpc_sm, sel_lta_fpc_sm);
Mclocks.warning_count = Mclocks.warning_count + 1;
end
// synopsys translate_on
// Expanded macro end.
wire fpc_low = fpc[2];
Mflipflop_30 p_fpc_reg_30(p_fpc,fpc,ss_clock,hold) ;
// DPC REGISTER
wire [31:2] dpc_muxout
;
// Expanded macro begin.
// cmux2(dpc_muxin, 30, dpc_muxout, fpc, dpc, hld_dpc)
function [30:1] dpc_muxin ;
input [30:1] in0_fn ;
input [30:1] in1_fn ;
input select_fn ;
reg [30: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
dpc_muxin = out_fn ;
end
endfunction
assign dpc_muxout = dpc_muxin( fpc, dpc, hld_dpc) ;
// Expanded macro end.
wire [31:2] ndpc
;
// Expanded macro begin.
// cmux2(ndpc_mux, 30, ndpc, dpc_muxout, ({30'b0}), reset)
function [30:1] ndpc_mux ;
input [30:1] in0_fn ;
input [30:1] in1_fn ;
input select_fn ;
reg [30: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
ndpc_mux = out_fn ;
end
endfunction
assign ndpc = ndpc_mux(dpc_muxout, ({30'b0}), reset) ;
// Expanded macro end.
wire ndpc_low = ndpc[2];
Mflipflop_30 dpc_register_30( dpc, ndpc, ss_clock, hold) ;
// EPC REGISTER
wire [31:2] epc
; // epc
Mflipflop_30 epc_register_30( epc, dpc, ss_clock, hold) ;
wire [31:2] iu_epc = epc;
// WPC REGISTER
// reg was held by rtrap_hldpc
wire [31:2] wpc;
Mflipflop_30 wpc_register_30( wpc, epc, ss_clock, hold) ;
// TPC REGISTER
// reg was held by rtrap_hldpc
wire [31:2] tpc_almost
;
Mflipflop_30 tpc_register_30( tpc_almost, wpc, ss_clock, hold) ;
wire [31:2] tpcm4
= tpc_almost - ({29'b0,1'b1});
wire [31:2] tpc;
// Expanded macro begin.
// cmux3d(tpc_mux, 30, tpc, wpc, fwd_wpc_sm, tpc_almost, use_tpc_sm, tpcm4, fwd_tpcm4_sm)
function [30:1] tpc_mux ;
input [30:1] in0_fn ;
input s0_fn ;
input [30:1] in1_fn ;
input s1_fn ;
input [30:1] in2_fn ;
input s2_fn ;
reg [30:1] out_fn ;
begin
case ({ fwd_tpcm4_sm, use_tpc_sm, fwd_wpc_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
tpc_mux = out_fn ;
end
endfunction
assign tpc = tpc_mux( wpc, fwd_wpc_sm, tpc_almost, use_tpc_sm, tpcm4, fwd_tpcm4_sm) ;
// synopsys translate_off
always @ (posedge(~Mclocks.clock))
#1 if (( fwd_tpcm4_sm+ use_tpc_sm+ fwd_wpc_sm !== 1) & `SS_SCOPE.input_reset_l &
~Mtask.trace.ppr & ~( fwd_tpcm4_sm+ use_tpc_sm^ fwd_wpc_sm===1'bx)) begin
$display("### %m.tpc_mux: CMUX3D select error!\n");
$display(" fwd_tpcm4_sm, use_tpc_sm, fwd_wpc_sm=%0d%0d%0d\n", fwd_tpcm4_sm, use_tpc_sm, fwd_wpc_sm);
Mclocks.warning_count = Mclocks.warning_count + 1;
end
// synopsys translate_on
// Expanded macro end.
//-----------------------------------------------------------------------------
// DISPLAY TASK
// synopsys translate_off
task disp;
begin
$write("ADR: %x ", {iu_iva_g,2'b00});
if(hld_car_mar_real) $write("HELD");
else begin
$write("next: %x ", {iu_iva_g,2'b00});
$write("FROM ");
if(reset) $write("RESET ");
else if(gpcadr_default)$write("ADDER ");
else begin
if(sadr_jmprett)$write("ALU ");
if(sadr_tbr)$write("TBR ");
if(sel_recirc | sel_recirc_inc) begin
// if(I_cache_adr+8 == adr_plus)
// $write("ADR + 8 ");
// else if(I_cache_adr+4 == adr_plus)
// $write("ADR + 4 ");
// else if(I_cache_adr == adr_plus)
// $write("ADR");
// else
$write("???");
end
// if(sel_mar_adr)$write("MAR (high)");
// if(sel_fpc_hadr)$write("CAR (high)");
// if(sel_gpc_hadr)$write("GPC (high)");
// if(sel_lomar_adr)$write("MAR (low)");
// if(sel_fpc_ladr)$write("CAR (low)");
// if(sel_gpc_hadr)$write("GPC (low)");
end
end
$display;
$write("CAR: %x ", {car,2'b00});
if(hld_car_mar_real) $write("HELD");
else
$write("next: %x ", {iu_iva_g,2'b00});
$display;
$write("MAR: %x ", {mar,2'b00});
if(hld_car_mar_real) $write("HELD");
else
$write("next: %x ", {iu_iva_g,2'b00});
$display;
// $write("DPC: %x ", dpc);
// if(hld_dpc) $write("HELD");
// else begin
// $write("next: %x ", {~ndpc_, 2'b00});
// $write("FROM ");
// if(ndpc_adr_reg)$write("ADR");
// else $write("INC");
// end
// $display;
$display("DPC: %x", dpc);
$display("EPC: %x", epc);
$display("WPC: %x", wpc);
// $write("PC_BUF: %x ", {pc_buf, 2'b00});
// if(hld_pc_buf) $write("HELD");
// else begin
// $write("next: %x ", adr_plus);
// $write("FROM ");
// if(~adr_+8 == adr_plus) $write("ADR + 8 ");
// else if(~adr_+4 == adr_plus) $write("ADR + 4 ");
// else if(~adr_ == adr_plus) $write("ADR");
// else $write("???");
// end
// $display;
$display("---------------------------------------------------------------------------");
#0 Mclocks.STOP = ~Mclocks.STOP;
end
endtask
// synopsys translate_on
endmodule
/*
* not needed anymore (at least not for now)
module Madder (aa_out, aa_src1, dpc);
output [31:2] aa_out;
input [31:2] aa_src1;
input [31:2] dpc;
wire [31:2] aa_out = aa_src1 + dpc;
endmodule
module Mincrementer (adr_plus_muxin, car);
output [31:2] adr_plus_muxin;
input [31:2] car;
wire [31:2] adr_plus_muxin = car[31:2] + ({29'b0, 1'b1});
endmodule
*/
/*
* stuff removed that is used in tsunami
*/
/*
// Add register for pipelining - into spr slice fo Mpc
REGWIRE pic_sel_fillp;
REG(pic_sel_fillp_reg,1,pic_sel_fillp,ic_sel_fillp, ss_clock,1'b0)
*/
/* for tsunami
// Fill pointer register from IC
REGWIRE [4:2] fillp;
REG(fillp_reg,3,fillp,ic_nfillp,ss_clock,1'b0)
*/
/* for tsunami
wire [31:5] ihigh_address;
wire [4:2] ilow_address;
// reg [1:0] ibyte_address;
CMUX4D(ihigh_adrmux,27,ihigh_address, gpc_adr[31:5], sel_gpc_hadr, car[31:5], sel_fpc_hadr, mar[31:5], sel_mar_adr, ({20'b0,low_D_cache_adr[11:5]}), ic_sel_dva)
CMUX5D(ilow_addrmux,3,ilow_address, gpc_adr[4:2], sel_gpc_ladr_sm, car[4:2], sel_fpc_ladr, mar[4:2], sel_lomar_adr, low_D_cache_adr[4:2], ic_sel_dva_sm, fillp[4:2], ic_sel_fillp_sm)
assign I_cache_adr = {ihigh_address,ilow_address[4:3],1'b0};
*/
/*
MUX3D(ibyte_adrmux,2,ibyte_address, gpc_adr[1:0], sel_gpc_hadr, car[1:0], sel_fpc_hadr, mar[1:0], sel_mar_adr)
assign I_cache_adr = {ihigh_address,ilow_address,ibyte_address};
*/
/* for tsunami
// I_DATA_AVAIL determination
wire match_gpcfillp = gpc_adr[4:2] == fillp[4:2];
wire match_carfillp = car[4:2] == fillp[4:2];
wire match_marfillp = mar[4:2] == fillp[4:2];
// These are changes on polarity
wire match_gpcfillp_l = ~match_gpcfillp;
wire match_carfillp_l = ~match_carfillp;
wire match_marfillp_l = ~match_marfillp;
REGWIRE pmatch_gpcfillp;
REG(match_gpcfillp_reg,1,pmatch_gpcfillp,match_gpcfillp_l, ss_clock,1'b0)
REGWIRE pmatch_carfillp;
REG(match_carfillp_reg,1,pmatch_carfillp,match_carfillp_l, ss_clock,1'b0)
REGWIRE pmatch_marfillp;
REG(match_marfillp_reg,1,pmatch_marfillp,match_marfillp_l, ss_clock,1'b0)
wire match_fillp;
CMUX3D(match_fillp_mux,1,match_fillp, pmatch_gpcfillp, sel_gpc_comp_sm, pmatch_carfillp, sel_fpc_comp_sm, pmatch_marfillp, sel_mar_comp_sm)
wire id_avail_qualify_l = pic_sel_fillp & match_fillp;
// REGWIRE id_avail_qualify_l;
// REG(id_avail_qual_reg,1,id_avail_qualify_l,nid_avail_qualify_l, // ss_clock, 1'b0)
wire i_data_avail = ic_instr_avail & ~id_avail_qualify_l;
*/
This page: |
Created: | Thu Aug 19 12:03:38 1999 |
| From: |
../../../sparc_v8/ssparc/iu/Mpc/rtl/pc.v
|