/******************************************************************************/
/* */
/* 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. */
/* */
/******************************************************************************/
// @(#)dwait.v 1.20 4/5/93
/******************************************************************************
// Description:
// This is the hold control block, to hold the IU when we definitely know
// that a request cannot be serviced..
// It has only 1 output dwait_w
//
******************************************************************************/
module dwait
(
possible_bad_ld_op_w,
parity_error_d1, // From f/f in rl_dc_cntl
parity_error_in_fill, // From f/f in rl_dc_cntl
first_w_of_cache_ram_asi,
potential_write_dcache_e,
mm_dcache_enbl_d1, // From MMU out of a register
dcc_idle, // From f/f in rl_dc_cntl
iu_in_trap_d1, // From f/f in rl_dc_cntl
ld_op_w, // From f/f in rl_dc_cntl
st_op_w, // From f/f in rl_dc_cntl
dcc_stat_wait,
dcc_stat, // From f/f in rl_dc_cntl
dcc_fill_wait,
dcc_fill_write_l,
dcc_dead_cyc,
dcc_dead_cyc_3,
normal_asi_w, // From f/f in rl_dc_cntl
hold_after_last_stream, // From f/f in rl_dc_cntl
st_stream_hold,
dcc_nc_wait,
dcc_nc_retry,
dcc_nc_bypass,
nomiss_asi_w, // From f/f in rl_dc_cntl
bad_st_inv_hold,
dc_flush_op_w, // From f/f in rl_dc_cntl
dc_flush_hold, // From f/f in rl_dc_cntl
standby_req, // From clock cntrl out of a register
dc_standby_w, // From f/f in rl_dc_cntl
flush123_out, // From f/f in rl_dc_cntl
dmar, // From f/f in rl_dc_cntl
iu_dva_w, // From f/f in rl_dc_cntl
dwait_w
);
input possible_bad_ld_op_w
;
input parity_error_d1
;
input parity_error_in_fill
;
input first_w_of_cache_ram_asi
;
input mm_dcache_enbl_d1
;
input dcc_idle
;
input iu_in_trap_d1
;
input ld_op_w
;
input st_op_w
;
input dcc_stat_wait
;
input dcc_stat
;
input dcc_fill_wait
;
input dcc_fill_write_l
;
input dcc_dead_cyc
;
input dcc_dead_cyc_3
;
input potential_write_dcache_e
;
input normal_asi_w
;
input hold_after_last_stream
;
input st_stream_hold
;
input dcc_nc_wait
;
input dcc_nc_retry
;
input dcc_nc_bypass
;
input nomiss_asi_w
;
input bad_st_inv_hold
;
input dc_flush_op_w
;
input dc_flush_hold
;
input standby_req
;
input dc_standby_w
;
input flush123_out
;
input [12:3] dmar
;
input [12:3] iu_dva_w
;
output dwait_w
;
// Address matches used for streaming analysis.
// Note: these are hard-coded for an 8KB cache, to facilitate synthesis.
// When running with a larger cache (i.e. cache mode), we can get
// some needless streaming misses if we access a line whose
// DVA differs from the line we're filling only in bits 15:13.
// Used only during dcc_fill_write_l
wire same_dw_w
= (iu_dva_w[3]==~dmar[3]) ;
// Used only during dcc_fill_write_l and dcc_dead_cyc
wire same_line_w
= (iu_dva_w[12:4]==dmar[12:4]) ;
// Used only during dcc_dead_cyc
wire dw_filled_w
= (iu_dva_w[3]==dmar[3]) ;
assign dwait_w =
(
// Hold on the first cycle when cache is disabled, or for most ASI ops.
// why the ~iu_in_trap_d1 term? Why is it OK not to cancel a load
// or store which traps in the IU in W?
(dcc_idle & ~iu_in_trap_d1 & (ld_op_w|st_op_w) & ~nomiss_asi_w
& (~mm_dcache_enbl_d1 | ~normal_asi_w))
// Hold during these states, when data is not back yet.
// Stores can be released earlier..
// ..but we don't. In the noncached store case, this is because we haven't
// made provisions for dealing with a subsequent load or store which
// streams into W during dcc_st_nc_bypass or dcc_st_nc_retry.
// Before this change, afxcomboQ1,c_pa got bad data when a LdA (pc=12a8)
// streamed through W during a noncached store (no bug report).
| dcc_stat_wait
| dcc_stat
| dcc_fill_wait
| dcc_nc_wait
// This state was added to remove an iu_held term from the cache write controls
| dcc_nc_retry
// Atomics must be held in W until the last fill write or noncached bypass is
// completed (the MMU requires this).
| (st_op_w & ld_op_w & ~dcc_idle & ~dcc_nc_bypass)
// Added for Store Streaming.
// Don't stream a Store from E to W if it will write the not-yet-filled DW -
// otherwise, the stored value will get wiped out by the DW fill.
| st_stream_hold
// Why is this here? - we're done with the fill after dcc_fill_write_l
// | (dcc_fill_write_l & st_to_fill_dw_e_d1)
// Streaming holds, if not able to stream during 2nd fill cycle and if the
// asi is not a normal or nomiss_asi(BUG #461).
| (dcc_fill_write_l &
((~(same_line_w & same_dw_w) | ~normal_asi_w) & (st_op_w|ld_op_w)))
// Hold, if not able to stream during deadcyles, or during asi accesses.
| ( dcc_dead_cyc & ((same_line_w & ~dw_filled_w & (st_op_w|ld_op_w))
| ~normal_asi_w ))
// Hold when D$ sm is idle, if the previous instruction was a missed asi ld/st
| hold_after_last_stream
// Hold on st traps to write V bit
| bad_st_inv_hold
// Hold IU during I$,IT,DT asi's. These asi's are handled as non-cached op's,
// whereas D$ asi's are still 1 cycle operations.
// why do we hold only for the first W-cycle?
| first_w_of_cache_ram_asi
// Hold dwait for 1 cycle after the W cycle of Flush, (weird flush interface).
| dc_flush_op_w
// After that hold untill I$ flushes its corresponding line
| dc_flush_hold
// Power management holds
// Hold if D$ sm in idle and no flush instruction in progress.
| (standby_req & dcc_idle & ~(dc_flush_op_w | dc_flush_hold))
// Also prevent any new ld/st's from starting
| dc_standby_w
// Hold on icache asi for 4 cycles. dva->iva for 3 cycles after mm_dstat_avail
| flush123_out
// Hold for 1 cycle on parity errors, for cornercase: error on other
// half of cacheline followed by a load of that word.
| parity_error_d1
// No streaming during parity errors.
| (dcc_dead_cyc & parity_error_in_fill)
// Unable to switch from iu_dva_e -> iu_dva_w due to timing reasons.
// 'iu_held' slow, so hold and retry, maybe the next around it will be o.k.
| possible_bad_ld_op_w )
// Resource Conflict for D$ RAM during 2nd half of fill.
// dcc_dead_cyc_3 may be the cycle before dcc_fill_write_l, so don't stream
// a store from E->W.
| (dcc_dead_cyc_3 & potential_write_dcache_e)
;
endmodule
This page: |
Created: | Thu Aug 19 12:00:20 1999 |
| From: |
../../../sparc_v8/ssparc/cc/rl_dc_cntl/rtl/dwait.v
|