diff --git a/src/mem/ruby/protocol/chi/CHI-cache-actions.sm b/src/mem/ruby/protocol/chi/CHI-cache-actions.sm index 34358050cf..6123a6c70d 100644 --- a/src/mem/ruby/protocol/chi/CHI-cache-actions.sm +++ b/src/mem/ruby/protocol/chi/CHI-cache-actions.sm @@ -2600,11 +2600,18 @@ action(Send_CompData, desc="") { bool is_rd_nsd := tbe.reqType == CHIRequestType:ReadNotSharedDirty; bool is_rd_unique := tbe.reqType == CHIRequestType:ReadUnique; - // if the config allows (or not caching the data) and line has no sharers - bool snd_unique_on_rs := (fwd_unique_on_readshared || tbe.dataToBeInvalid) + // Send UC/UD on ReadShared or ReadNotSharedDirty if the line has no sharers + // and one of the followings are met + // 1) the config allows or + // 2) local cache won't have the line or + // 3) Dirty will be passed but the request doesn't allow SD + bool snd_unique_on_rs := (fwd_unique_on_readshared || + tbe.dataToBeInvalid || + (tbe.dataDirty && is_rd_nsd)) && tbe.dataUnique && tbe.dir_sharers.isEmpty(); // if the request type allows and we won't be caching the data - bool snd_dirty_on_rs := is_rd_shared && !is_rd_nsd && tbe.dataToBeInvalid; + bool snd_dirty_on_rs := (is_rd_shared && !is_rd_nsd) && + !tbe.dir_ownerExists; if (is_rd_once) { tbe.snd_msgType := CHIDataType:CompData_I; diff --git a/src/mem/ruby/protocol/chi/CHI-cache-transitions.sm b/src/mem/ruby/protocol/chi/CHI-cache-transitions.sm index 31b5b0914a..9aaee236ac 100644 --- a/src/mem/ruby/protocol/chi/CHI-cache-transitions.sm +++ b/src/mem/ruby/protocol/chi/CHI-cache-transitions.sm @@ -767,7 +767,7 @@ transition({UD_RSC,SD_RSC}, Local_Eviction, BUSY_BLKD) {ReplTBEAvailable} { ProcessNextState; } -transition({UD_RSC,SD_RSC,UC_RSC,UD_RU,UC_RU,UD_RSD}, Global_Eviction, BUSY_BLKD) {ReplTBEAvailable} { +transition({UD_RSC,SD_RSC,UC_RSC,UD_RU,UC_RU,UD_RSD,SD_RSD}, Global_Eviction, BUSY_BLKD) {ReplTBEAvailable} { Initiate_Replacement; Initiate_Replacement_WB_BackInvalidate; Profile_Eviction;