summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mem/protocol/MESI_CMP_directory-L1cache.sm38
-rw-r--r--src/mem/protocol/MESI_CMP_directory-L2cache.sm42
-rw-r--r--src/mem/protocol/MESI_CMP_directory-dir.sm24
3 files changed, 66 insertions, 38 deletions
diff --git a/src/mem/protocol/MESI_CMP_directory-L1cache.sm b/src/mem/protocol/MESI_CMP_directory-L1cache.sm
index 934405786..91be3933f 100644
--- a/src/mem/protocol/MESI_CMP_directory-L1cache.sm
+++ b/src/mem/protocol/MESI_CMP_directory-L1cache.sm
@@ -136,6 +136,7 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
void unset_cache_entry();
void set_tbe(TBE a);
void unset_tbe();
+ void wakeUpBuffers(Address a);
// inclusive cache returns L1 entries only
Entry getCacheEntry(Address addr), return_by_pointer="yes" {
@@ -230,7 +231,7 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
out_port(unblockNetwork_out, ResponseMsg, unblockFromL1Cache);
// Response IntraChip L1 Network - response msg to this L1 cache
- in_port(responseIntraChipL1Network_in, ResponseMsg, responseToL1Cache) {
+ in_port(responseIntraChipL1Network_in, ResponseMsg, responseToL1Cache, rank = 2) {
if (responseIntraChipL1Network_in.isReady()) {
peek(responseIntraChipL1Network_in, ResponseMsg, block_on="Address") {
assert(in_msg.Destination.isElement(machineID));
@@ -268,7 +269,7 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
}
// Request InterChip network - request from this L1 cache to the shared L2
- in_port(requestIntraChipL1Network_in, RequestMsg, requestToL1Cache) {
+ in_port(requestIntraChipL1Network_in, RequestMsg, requestToL1Cache, rank = 1) {
if(requestIntraChipL1Network_in.isReady()) {
peek(requestIntraChipL1Network_in, RequestMsg, block_on="Address") {
assert(in_msg.Destination.isElement(machineID));
@@ -293,7 +294,7 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
}
// Mandatory Queue betweens Node's CPU and it's L1 caches
- in_port(mandatoryQueue_in, RubyRequest, mandatoryQueue, desc="...") {
+ in_port(mandatoryQueue_in, RubyRequest, mandatoryQueue, desc="...", rank = 0) {
if (mandatoryQueue_in.isReady()) {
peek(mandatoryQueue_in, RubyRequest, block_on="LineAddress") {
@@ -653,9 +654,6 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
}
}
- action(z_stall, "z", desc="Stall") {
- }
-
action(ff_deallocateL1CacheBlock, "\f", desc="Deallocate L1 cache block. Sets the cache to not present, allowing a replacement in parallel with a fetch.") {
if (L1DcacheMemory.isTagPresent(address)) {
L1DcacheMemory.deallocate(address);
@@ -677,12 +675,12 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
}
}
- action(zz_recycleRequestQueue, "zz", desc="recycle L1 request queue") {
- requestIntraChipL1Network_in.recycle();
+ action(z_stallAndWaitMandatoryQueue, "\z", desc="recycle L1 request queue") {
+ stall_and_wait(mandatoryQueue_in, address);
}
- action(z_recycleMandatoryQueue, "\z", desc="recycle L1 request queue") {
- mandatoryQueue_in.recycle();
+ action(kd_wakeUpDependents, "kd", desc="wake-up dependents") {
+ wakeUpBuffers(address);
}
action(uu_profileInstMiss, "\ui", desc="Profile the demand miss") {
@@ -702,8 +700,8 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
//*****************************************************
// Transitions for Load/Store/Replacement/WriteBack from transient states
- transition({IS, IM, IS_I, M_I, SM}, {Load, Ifetch, Store, L1_Replacement}) {
- z_recycleMandatoryQueue;
+ transition({IS, IM, IS_I, M_I, SM, SINK_WB_ACK}, {Load, Ifetch, Store, L1_Replacement}) {
+ z_stallAndWaitMandatoryQueue;
}
// Transitions from Idle
@@ -824,6 +822,7 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
transition(M_I, WB_Ack, I) {
s_deallocateTBE;
o_popIncomingResponseQueue;
+ kd_wakeUpDependents;
}
transition(M, Inv, I) {
@@ -871,6 +870,7 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
h_load_hit;
s_deallocateTBE;
o_popIncomingResponseQueue;
+ kd_wakeUpDependents;
}
transition(IS_I, Data_all_Acks, I) {
@@ -878,6 +878,7 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
h_load_hit;
s_deallocateTBE;
o_popIncomingResponseQueue;
+ kd_wakeUpDependents;
}
transition(IS, DataS_fromL1, S) {
@@ -886,6 +887,7 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
h_load_hit;
s_deallocateTBE;
o_popIncomingResponseQueue;
+ kd_wakeUpDependents;
}
transition(IS_I, DataS_fromL1, I) {
@@ -894,6 +896,7 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
h_load_hit;
s_deallocateTBE;
o_popIncomingResponseQueue;
+ kd_wakeUpDependents;
}
// directory is blocked when sending exclusive data
@@ -903,6 +906,7 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
jj_sendExclusiveUnblock;
s_deallocateTBE;
o_popIncomingResponseQueue;
+ kd_wakeUpDependents;
}
transition(IS, Data_Exclusive, E) {
@@ -911,6 +915,7 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
jj_sendExclusiveUnblock;
s_deallocateTBE;
o_popIncomingResponseQueue;
+ kd_wakeUpDependents;
}
// Transitions from IM
@@ -931,6 +936,7 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
jj_sendExclusiveUnblock;
s_deallocateTBE;
o_popIncomingResponseQueue;
+ kd_wakeUpDependents;
}
// transitions from SM
@@ -944,10 +950,7 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
hh_store_hit;
s_deallocateTBE;
o_popIncomingResponseQueue;
- }
-
- transition(SINK_WB_ACK, {Load, Store, Ifetch, L1_Replacement}){
- z_recycleMandatoryQueue;
+ kd_wakeUpDependents;
}
transition(SINK_WB_ACK, Inv){
@@ -955,8 +958,9 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
l_popRequestQueue;
}
- transition(SINK_WB_ACK, WB_Ack){
+ transition(SINK_WB_ACK, WB_Ack, I){
s_deallocateTBE;
o_popIncomingResponseQueue;
+ kd_wakeUpDependents;
}
}
diff --git a/src/mem/protocol/MESI_CMP_directory-L2cache.sm b/src/mem/protocol/MESI_CMP_directory-L2cache.sm
index 16c5bc5a1..9cc20f8c3 100644
--- a/src/mem/protocol/MESI_CMP_directory-L2cache.sm
+++ b/src/mem/protocol/MESI_CMP_directory-L2cache.sm
@@ -158,6 +158,7 @@ machine(L2Cache, "MESI Directory L2 Cache CMP")
void unset_cache_entry();
void set_tbe(TBE a);
void unset_tbe();
+ void wakeUpBuffers(Address a);
// inclusive cache, returns L2 entries only
Entry getCacheEntry(Address addr), return_by_pointer="yes" {
@@ -283,7 +284,7 @@ machine(L2Cache, "MESI Directory L2 Cache CMP")
out_port(responseIntraChipL2Network_out, ResponseMsg, responseFromL2Cache);
- in_port(L1unblockNetwork_in, ResponseMsg, unblockToL2Cache) {
+ in_port(L1unblockNetwork_in, ResponseMsg, unblockToL2Cache, rank = 2) {
if(L1unblockNetwork_in.isReady()) {
peek(L1unblockNetwork_in, ResponseMsg) {
Entry cache_entry := getCacheEntry(in_msg.Address);
@@ -305,7 +306,7 @@ machine(L2Cache, "MESI Directory L2 Cache CMP")
}
// Response IntraChip L2 Network - response msg to this particular L2 bank
- in_port(responseIntraChipL2Network_in, ResponseMsg, responseToL2Cache) {
+ in_port(responseIntraChipL2Network_in, ResponseMsg, responseToL2Cache, rank = 1) {
if (responseIntraChipL2Network_in.isReady()) {
peek(responseIntraChipL2Network_in, ResponseMsg) {
// test wether it's from a local L1 or an off chip source
@@ -349,7 +350,7 @@ machine(L2Cache, "MESI Directory L2 Cache CMP")
}
// L1 Request
- in_port(L1RequestIntraChipL2Network_in, RequestMsg, L1RequestToL2Cache) {
+ in_port(L1RequestIntraChipL2Network_in, RequestMsg, L1RequestToL2Cache, rank = 0) {
if(L1RequestIntraChipL2Network_in.isReady()) {
peek(L1RequestIntraChipL2Network_in, RequestMsg) {
Entry cache_entry := getCacheEntry(in_msg.Address);
@@ -791,14 +792,17 @@ machine(L2Cache, "MESI Directory L2 Cache CMP")
}
}
- action(zz_recycleL1RequestQueue, "zz", desc="recycle L1 request queue") {
- L1RequestIntraChipL2Network_in.recycle();
+ action(zz_stallAndWaitL1RequestQueue, "zz", desc="recycle L1 request queue") {
+ stall_and_wait(L1RequestIntraChipL2Network_in, address);
}
action(zn_recycleResponseNetwork, "zn", desc="recycle memory request") {
responseIntraChipL2Network_in.recycle();
}
+ action(kd_wakeUpDependents, "kd", desc="wake-up dependents") {
+ wakeUpBuffers(address);
+ }
//*****************************************************
// TRANSITIONS
@@ -820,7 +824,7 @@ machine(L2Cache, "MESI Directory L2 Cache CMP")
}
transition({IM, IS, ISS, SS_MB, M_MB, MT_MB, MT_IIB, MT_IB, MT_SB}, {L2_Replacement, L2_Replacement_clean}) {
- zz_recycleL1RequestQueue;
+ zz_stallAndWaitL1RequestQueue;
}
transition({IM, IS, ISS, SS_MB, M_MB, MT_MB, MT_IIB, MT_IB, MT_SB}, MEM_Inv) {
@@ -833,7 +837,7 @@ machine(L2Cache, "MESI Directory L2 Cache CMP")
transition({SS_MB, M_MB, MT_MB, MT_IIB, MT_IB, MT_SB}, {L1_GETS, L1_GET_INSTR, L1_GETX, L1_UPGRADE}) {
- zz_recycleL1RequestQueue;
+ zz_stallAndWaitL1RequestQueue;
}
@@ -885,6 +889,7 @@ machine(L2Cache, "MESI Directory L2 Cache CMP")
e_sendDataToGetSRequestors;
s_deallocateTBE;
o_popIncomingResponseQueue;
+ kd_wakeUpDependents;
}
transition(IM, Mem_Data, MT_MB) {
@@ -902,11 +907,11 @@ machine(L2Cache, "MESI Directory L2 Cache CMP")
}
transition({IS, ISS}, L1_GETX) {
- zz_recycleL1RequestQueue;
+ zz_stallAndWaitL1RequestQueue;
}
transition(IM, {L1_GETX, L1_GETS, L1_GET_INSTR}) {
- zz_recycleL1RequestQueue;
+ zz_stallAndWaitL1RequestQueue;
}
// transitions from SS
@@ -1018,30 +1023,35 @@ machine(L2Cache, "MESI Directory L2 Cache CMP")
// transitions from blocking states
transition(SS_MB, Unblock_Cancel, SS) {
k_popUnblockQueue;
+ kd_wakeUpDependents;
}
transition(MT_MB, Unblock_Cancel, MT) {
k_popUnblockQueue;
+ kd_wakeUpDependents;
}
transition(MT_IB, Unblock_Cancel, MT) {
k_popUnblockQueue;
+ kd_wakeUpDependents;
}
transition(SS_MB, Exclusive_Unblock, MT) {
// update actual directory
mmu_markExclusiveFromUnblock;
k_popUnblockQueue;
+ kd_wakeUpDependents;
}
transition({M_MB, MT_MB}, Exclusive_Unblock, MT) {
// update actual directory
mmu_markExclusiveFromUnblock;
k_popUnblockQueue;
+ kd_wakeUpDependents;
}
transition(MT_IIB, {L1_PUTX, L1_PUTX_old}){
- zz_recycleL1RequestQueue;
+ zz_stallAndWaitL1RequestQueue;
}
transition(MT_IIB, Unblock, MT_IB) {
@@ -1057,16 +1067,18 @@ machine(L2Cache, "MESI Directory L2 Cache CMP")
transition(MT_IB, {WB_Data, WB_Data_clean}, SS) {
m_writeDataToCache;
o_popIncomingResponseQueue;
+ kd_wakeUpDependents;
}
transition(MT_SB, Unblock, SS) {
nnu_addSharerFromUnblock;
k_popUnblockQueue;
+ kd_wakeUpDependents;
}
// writeback states
transition({I_I, S_I, MT_I, MCT_I, M_I}, {L1_GETX, L1_UPGRADE, L1_GETS, L1_GET_INSTR}) {
- zz_recycleL1RequestQueue;
+ zz_stallAndWaitL1RequestQueue;
}
transition(I_I, Ack) {
@@ -1091,7 +1103,7 @@ machine(L2Cache, "MESI Directory L2 Cache CMP")
}
transition(MCT_I, {L1_PUTX, L1_PUTX_old}){
- zz_recycleL1RequestQueue;
+ zz_stallAndWaitL1RequestQueue;
}
// L1 never changed Dirty data
@@ -1101,17 +1113,18 @@ machine(L2Cache, "MESI Directory L2 Cache CMP")
}
transition(MT_I, {L1_PUTX, L1_PUTX_old}){
- zz_recycleL1RequestQueue;
+ zz_stallAndWaitL1RequestQueue;
}
// possible race between unblock and immediate replacement
transition({MT_MB,SS_MB}, {L1_PUTX, L1_PUTX_old}) {
- zz_recycleL1RequestQueue;
+ zz_stallAndWaitL1RequestQueue;
}
transition(MT_I, WB_Data_clean, NP) {
s_deallocateTBE;
o_popIncomingResponseQueue;
+ kd_wakeUpDependents;
}
transition(S_I, Ack) {
@@ -1127,5 +1140,6 @@ machine(L2Cache, "MESI Directory L2 Cache CMP")
transition(M_I, Mem_Ack, NP) {
s_deallocateTBE;
o_popIncomingResponseQueue;
+ kd_wakeUpDependents;
}
}
diff --git a/src/mem/protocol/MESI_CMP_directory-dir.sm b/src/mem/protocol/MESI_CMP_directory-dir.sm
index d026e7b90..aa1294b2c 100644
--- a/src/mem/protocol/MESI_CMP_directory-dir.sm
+++ b/src/mem/protocol/MESI_CMP_directory-dir.sm
@@ -109,6 +109,7 @@ machine(Directory, "MESI_CMP_filter_directory protocol")
void set_tbe(TBE tbe);
void unset_tbe();
+ void wakeUpBuffers(Address a);
Entry getDirectoryEntry(Address addr), return_by_pointer="yes" {
Entry dir_entry := static_cast(Entry, "pointer", directory[addr]);
@@ -191,7 +192,7 @@ machine(Directory, "MESI_CMP_filter_directory protocol")
// ** IN_PORTS **
- in_port(requestNetwork_in, RequestMsg, requestToDir) {
+ in_port(requestNetwork_in, RequestMsg, requestToDir, rank = 0) {
if (requestNetwork_in.isReady()) {
peek(requestNetwork_in, RequestMsg) {
assert(in_msg.Destination.isElement(machineID));
@@ -211,7 +212,7 @@ machine(Directory, "MESI_CMP_filter_directory protocol")
}
}
- in_port(responseNetwork_in, ResponseMsg, responseToDir) {
+ in_port(responseNetwork_in, ResponseMsg, responseToDir, rank = 1) {
if (responseNetwork_in.isReady()) {
peek(responseNetwork_in, ResponseMsg) {
assert(in_msg.Destination.isElement(machineID));
@@ -228,7 +229,7 @@ machine(Directory, "MESI_CMP_filter_directory protocol")
}
// off-chip memory request/response is done
- in_port(memQueue_in, MemoryMsg, memBuffer) {
+ in_port(memQueue_in, MemoryMsg, memBuffer, rank = 2) {
if (memQueue_in.isReady()) {
peek(memQueue_in, MemoryMsg) {
if (in_msg.Type == MemoryRequestType:MEMORY_READ) {
@@ -244,7 +245,6 @@ machine(Directory, "MESI_CMP_filter_directory protocol")
}
-
// Actions
action(a_sendAck, "a", desc="Send ack to L2") {
peek(responseNetwork_in, ResponseMsg) {
@@ -297,6 +297,10 @@ machine(Directory, "MESI_CMP_filter_directory protocol")
memQueue_in.dequeue();
}
+ action(kd_wakeUpDependents, "kd", desc="wake-up dependents") {
+ wakeUpBuffers(address);
+ }
+
action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
peek(requestNetwork_in, RequestMsg) {
enqueue(memQueue_out, MemoryMsg, latency=to_mem_ctrl_latency) {
@@ -400,8 +404,8 @@ machine(Directory, "MESI_CMP_filter_directory protocol")
}
}
- action(z_recycleRequestQueue, "z", desc="recycle request queue") {
- requestNetwork_in.recycle();
+ action(z_stallAndWaitRequest, "z", desc="recycle request queue") {
+ stall_and_wait(requestNetwork_in, address);
}
action(zz_recycleDMAQueue, "zz", desc="recycle DMA queue") {
@@ -502,6 +506,7 @@ machine(Directory, "MESI_CMP_filter_directory protocol")
transition(IM, Memory_Data, M) {
d_sendData;
l_popMemQueue;
+ kd_wakeUpDependents;
}
//added by SS
transition(M, CleanReplacement, I) {
@@ -520,6 +525,7 @@ machine(Directory, "MESI_CMP_filter_directory protocol")
c_clearOwner;
aa_sendAck;
l_popMemQueue;
+ kd_wakeUpDependents;
}
@@ -532,6 +538,7 @@ machine(Directory, "MESI_CMP_filter_directory protocol")
transition(ID, Memory_Data, I) {
dr_sendDMAData;
l_popMemQueue;
+ kd_wakeUpDependents;
}
transition(I, DMA_WRITE, ID_W) {
@@ -543,10 +550,11 @@ machine(Directory, "MESI_CMP_filter_directory protocol")
transition(ID_W, Memory_Ack, I) {
da_sendDMAAck;
l_popMemQueue;
+ kd_wakeUpDependents;
}
transition({ID, ID_W, M_DRDI, M_DWRI, IM, MI}, {Fetch, Data} ) {
- z_recycleRequestQueue;
+ z_stallAndWaitRequest;
}
transition({ID, ID_W, M_DRD, M_DRDI, M_DWR, M_DWRI, IM, MI}, {DMA_WRITE, DMA_READ} ) {
@@ -570,6 +578,7 @@ machine(Directory, "MESI_CMP_filter_directory protocol")
aa_sendAck;
c_clearOwner;
l_popMemQueue;
+ kd_wakeUpDependents;
}
transition(M, DMA_WRITE, M_DWR) {
@@ -591,6 +600,7 @@ machine(Directory, "MESI_CMP_filter_directory protocol")
da_sendDMAAck;
w_deallocateTBE;
l_popMemQueue;
+ kd_wakeUpDependents;
}
}