Own_GETX, desc="We observe our own GetX forwarded back to us";
Fwd_GETX, desc="A GetX from another processor";
Fwd_GETS, desc="A GetS from another processor";
+ Fwd_DMA, desc="A GetS from another processor";
Inv, desc="Invalidations from the directory";
// Responses
assert(in_msg.Destination.isElement(machineID));
DEBUG_EXPR("MRM_DEBUG: L1 received");
DEBUG_EXPR(in_msg.Type);
-if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestType:DMA_READ || in_msg.Type == CoherenceRequestType:DMA_WRITE) {
+if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestType:DMA_WRITE) {
if (in_msg.Requestor == machineID && in_msg.RequestorMachine == MachineType:L1Cache) {
trigger(Event:Own_GETX, in_msg.Address);
} else {
}
} else if (in_msg.Type == CoherenceRequestType:GETS) {
trigger(Event:Fwd_GETS, in_msg.Address);
+ } else if (in_msg.Type == CoherenceRequestType:DMA_READ) {
+ trigger(Event:Fwd_DMA, in_msg.Address);
} else if (in_msg.Type == CoherenceRequestType:WB_ACK) {
trigger(Event:Writeback_Ack, in_msg.Address);
} else if (in_msg.Type == CoherenceRequestType:WB_ACK_DATA) {
zz_recycleMandatoryQueue;
}
- transition({M_W, MM_W}, {Fwd_GETS, Fwd_GETX, Own_GETX, Inv}) {
+ transition({M_W, MM_W}, {Fwd_GETS, Fwd_DMA, Fwd_GETX, Own_GETX, Inv}) {
z_recycleRequestQueue;
}
l_popForwardQueue;
}
- transition(S, Fwd_GETS) {
+ transition(S, {Fwd_GETS, Fwd_DMA}) {
e_sendData;
l_popForwardQueue;
}
l_popForwardQueue;
}
- transition(O, Fwd_GETS) {
+ transition(O, {Fwd_GETS, Fwd_DMA}) {
e_sendData;
l_popForwardQueue;
}
l_popForwardQueue;
}
+ transition(MM, Fwd_DMA, MM) {
+ //ee_sendDataExclusive;
+ e_sendData;
+ l_popForwardQueue;
+ }
+
// Transitions from M
transition({M, M_W}, {Load, Ifetch}) {
h_load_hit;
l_popForwardQueue;
}
+ transition(M, Fwd_DMA, M) {
+ e_sendData;
+ l_popForwardQueue;
+ }
+
// Transitions from IM
transition(IM, Inv) {
n_popResponseQueue;
}
- transition(SM, Fwd_GETS) {
+ transition(SM, {Fwd_DMA, Fwd_GETS}) {
e_sendData;
l_popForwardQueue;
}
l_popForwardQueue;
}
- transition(OM, Fwd_GETS, OM) {
+ transition(OM, {Fwd_DMA, Fwd_GETS}, OM) {
e_sendData;
l_popForwardQueue;
}
l_popForwardQueue;
}
+ transition(MI, Fwd_DMA, MI) {
+ q_sendDataFromTBEToCache;
+ l_popForwardQueue;
+ }
+
transition(MI, Fwd_GETX, II) {
q_sendExclusiveDataFromTBEToCache;
l_popForwardQueue;
}
- transition({SI, OI}, Fwd_GETS) {
+ transition({SI, OI}, {Fwd_DMA, Fwd_GETS}) {
q_sendDataFromTBEToCache;
l_popForwardQueue;
}
L1_PUTS, desc="local sharer wants to writeback";
Fwd_GETX, desc="A GetX from another processor";
Fwd_GETS, desc="A GetS from another processor";
+ Fwd_DMA, desc="A request from DMA";
Own_GETX, desc="A GetX from this node";
Inv, desc="Invalidations from the directory";
in_port(requestNetwork_in, RequestMsg, GlobalRequestToL2Cache) {
if (requestNetwork_in.isReady()) {
peek(requestNetwork_in, RequestMsg) {
- if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestType:DMA_READ || in_msg.Type == CoherenceRequestType:DMA_WRITE) {
+ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestType:DMA_WRITE) {
if (in_msg.Requestor == machineID) {
trigger(Event:Own_GETX, in_msg.Address);
} else {
}
} else if (in_msg.Type == CoherenceRequestType:GETS) {
trigger(Event:Fwd_GETS, in_msg.Address);
+ } else if(in_msg.Type == CoherenceRequestType:DMA_READ) {
+ trigger(Event:Fwd_DMA, in_msg.Address);
} else if (in_msg.Type == CoherenceRequestType:INV) {
trigger(Event:Inv, in_msg.Address);
} else if (in_msg.Type == CoherenceRequestType:WB_ACK) {
zz_recycleResponseQueue;
}
- transition({IFGX, IFGS, ISFGS, IFGXX, IFLXO, OFGX, ILOW, ILOXW, ILOSW, ILOSXW, SLSW, OLSW, ILSW, IW, OW, SW, OXW, OLSXW, ILXW, IFLS, IFLO, IFLOX, IFLOXX, IFLOSX,OLSXS, MM, SS, OO, SLSS, OLSS, OLSF, IGMIOFS}, {Fwd_GETX, Fwd_GETS, Inv}) {
+ transition({IFGX, IFGS, ISFGS, IFGXX, IFLXO, OFGX, ILOW, ILOXW, ILOSW, ILOSXW, SLSW, OLSW, ILSW, IW, OW, SW, OXW, OLSXW, ILXW, IFLS, IFLO, IFLOX, IFLOXX, IFLOSX,OLSXS, IGS, IGM, MM, SS, OO, SLSS, OLSS, OLSF, IGMIOFS}, {Fwd_GETX, Fwd_GETS, Fwd_DMA}) {
+ zz_recycleRequestQueue;
+ }
+
+ transition({IFGX, IFGS, ISFGS, IFGXX, IFLXO, OFGX, ILOW, ILOXW, ILOSW, ILOSXW, SLSW, OLSW, ILSW, IW, OW, SW, OXW, OLSXW, ILXW, IFLS, IFLO, IFLOX, IFLOXX, IFLOSX,OLSXS, MM, SS, OO, SLSS, OLSS, OLSF, IGMIOFS}, {Inv}) {
+ zz_recycleRequestQueue;
+ }
+
+ transition({IGM, IGS}, {Own_GETX}) {
zz_recycleRequestQueue;
}
m_popRequestQueue;
}
+ transition({ILOS, ILOSX}, Fwd_DMA) {
+ i_allocateTBE;
+ t_recordFwdSID;
+ j_forwardGlobalRequestToLocalOwner;
+ m_popRequestQueue;
+ }
+
+ transition({ILO, ILX, ILOX}, Fwd_DMA) {
+ i_allocateTBE;
+ t_recordFwdSID;
+ j_forwardGlobalRequestToLocalOwner;
+ m_popRequestQueue;
+ }
+
+ transition({ILOS, ILOSX, ILO, ILX, ILOX, ILXW}, Data) {
+ i_copyDataToTBE;
+ c_sendDataFromTBEToFwdGETS;
+ s_deallocateTBE;
+ n_popResponseQueue;
+ }
+
transition(IFGS, Data, ILO) {
i_copyDataToTBE;
c_sendDataFromTBEToFwdGETS;
m_popRequestQueue;
}
- transition({O, OLS}, Fwd_GETS) {
+ transition({O, OLS}, {Fwd_GETS, Fwd_DMA}) {
dd_sendDataToFwdGETS;
m_popRequestQueue;
}
m_popRequestQueue;
}
+ transition(OLSX, Fwd_DMA) {
+ dd_sendDataToFwdGETS;
+ m_popRequestQueue;
+ }
transition(M, Fwd_GETX, I) {
dd_sendDataToFwdGETX;
m_popRequestQueue;
}
+ transition(M, Fwd_DMA) {
+ dd_sendExclusiveDataToFwdGETS;
+ m_popRequestQueue;
+ }
transition({OLS, OLSX}, Fwd_GETX, OLSF) {
i_allocateTBE;
n_popResponseQueue;
}
-
-
// LOCAL REQUESTS THAT MUST ISSUE
transition(NP, {L1_PUTS, L1_PUTX, L1_PUTO}) {
o_popL1RequestQueue;
}
- transition(OGMIO, Fwd_GETS) {
+ transition(OGMIO, {Fwd_GETS, Fwd_DMA}) {
t_recordFwdSID;
c_sendDataFromTBEToFwdGETS;
m_popRequestQueue;
m_popRequestQueue;
}
+ transition(IGMIO, Fwd_DMA) {
+ t_recordFwdSID;
+ j_forwardGlobalRequestToLocalOwner;
+ m_popRequestQueue;
+ }
+
transition(IGMIOFS, Data, IGMIO) {
i_copyDataToTBE;
c_sendDataFromTBEToFwdGETS;
}
- transition(IGMO, Fwd_GETS) {
+ transition(IGMO, {Fwd_GETS, Fwd_DMA}) {
t_recordFwdSID;
c_sendDataFromTBEToFwdGETS;
m_popRequestQueue;
n_popTriggerQueue;
}
- transition(OLSI, Fwd_GETS) {
+ transition(OLSI, {Fwd_GETS, Fwd_DMA}) {
t_recordFwdSID;
c_sendDataFromTBEToFwdGETS;
m_popRequestQueue;
}
- transition({MI, OI}, Fwd_GETS, OI) {
+ transition({MI, OI}, {Fwd_GETS, Fwd_DMA}, OI) {
t_recordFwdSID;
c_sendDataFromTBEToFwdGETS;
m_popRequestQueue;
}
}
+ action(p_fwdDataToDMA, "\d", desc="Send data to requestor") {
+ peek(requestQueue_in, RequestMsg) {
+ enqueue(responseNetwork_out, ResponseMsg, latency="1") {
+ out_msg.Address := address;
+ out_msg.Sender := machineID;
+ out_msg.SenderMachine := MachineType:Directory;
+ out_msg.Destination.add(in_msg.Requestor);
+ out_msg.DataBlk := directory[in_msg.Address].DataBlk;
+ out_msg.Dirty := false; // By definition, the block is now clean
+ out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
+ out_msg.MessageSize := MessageSizeType:Response_Data;
+ }
+ }
+ }
+
+
+
action(e_ownerIsUnblocker, "e", desc="The owner is now the unblocker") {
peek(unblockNetwork_in, ResponseMsg) {
directory[address].Owner.clear();
i_popIncomingRequestQueue;
}
- transition(XI_M, Memory_Data, XI_U) {
+ transition(XI_M, Memory_Data, I) {
d_sendDataMsg; // ack count may be zero
q_popMemQueue;
}
i_popIncomingRequestQueue;
}
- transition(S, DMA_READ, XI_M) {
- qf_queueMemoryFetchRequest;
- g_sendInvalidations; // the DMA will collect the invalidations then send an Unblock Exclusive
+ transition(S, DMA_READ, S) {
+ //qf_queueMemoryFetchRequest;
+ p_fwdDataToDMA;
+ //g_sendInvalidations; // the DMA will collect the invalidations then send an Unblock Exclusive
i_popIncomingRequestQueue;
}
i_popIncomingRequestQueue;
}
- transition(O, DMA_READ, XI_U) {
+ transition(O, DMA_READ, O) {
f_forwardRequest; // this will cause the data to go to DMA directly
- g_sendInvalidations; // this will cause acks to be sent to the DMA
+ //g_sendInvalidations; // this will cause acks to be sent to the DMA
i_popIncomingRequestQueue;
}
}
// no exclusive unblock will show up to the directory
- transition(M, DMA_READ, XI_U) {
+ transition(M, DMA_READ, M) {
f_forwardRequest; // this will cause the data to go to DMA directly
i_popIncomingRequestQueue;
}