MII, AccessPermission:Busy, desc="Blocked, doing writeback, was M, got Fwd_GETX";
OLSI, AccessPermission:Busy, desc="Blocked, doing writeback, was OLS";
ILSI, AccessPermission:Busy, desc="Blocked, doing writeback, was OLS got Fwd_GETX";
+
+ // DMA blocking states
+ ILOSD, AccessPermission:Busy, desc="Blocked, waiting for DMA ack";
+ ILOSXD, AccessPermission:Busy, desc="Blocked, waiting for DMA ack";
+ ILOD, AccessPermission:Busy, desc="Blocked, waiting for DMA ack";
+ ILXD, AccessPermission:Busy, desc="Blocked, waiting for DMA ack";
+ ILOXD, AccessPermission:Busy, desc="Blocked, waiting for DMA ack";
}
// EVENTS
Unblock, desc="Local L1 is telling L2 dir to unblock";
Exclusive_Unblock, desc="Local L1 is telling L2 dir to unblock";
-
+ DmaAck, desc="DMA ack from local L1";
// events initiated by this L2
L2_Replacement, desc="L2 Replacement", format="!r";
trigger(Event:L1_WBCLEANDATA, in_msg.Address,
cache_entry, TBEs[in_msg.Address]);
}
+ } else if (in_msg.Type == CoherenceResponseType:DMA_ACK) {
+ trigger(Event:DmaAck, in_msg.Address,
+ getCacheEntry(in_msg.Address), TBEs[in_msg.Address]);
} else {
error("Unexpected message");
}
}
}
+ action(cd_sendDataFromTBEToFwdDma, "cd", desc="Send data from TBE to external GETX") {
+ assert(is_valid(tbe));
+ peek(requestNetwork_in, RequestMsg) {
+ enqueue(responseNetwork_out, ResponseMsg, latency=response_latency) {
+ out_msg.Address := address;
+ out_msg.Type := CoherenceResponseType:DATA;
+ out_msg.Sender := machineID;
+ out_msg.Destination.add(in_msg.Requestor);
+ out_msg.DataBlk := tbe.DataBlk;
+ // out_msg.Dirty := tbe.Dirty;
+ // shared data should be clean
+ out_msg.Dirty := false;
+ out_msg.Acks := tbe.Fwd_GETX_ExtAcks;
+ out_msg.MessageSize := MessageSizeType:Response_Data;
+ }
+ }
+ DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
+ address, tbe.DataBlk);
+ }
+
action(c_sendDataFromTBEToFwdGETS, "ccc", desc="Send data from TBE to external GETX") {
assert(is_valid(tbe));
enqueue(responseNetwork_out, ResponseMsg, latency=response_latency) {
assert(is_valid(tbe));
tbe.DataBlk := in_msg.DataBlk;
tbe.Dirty := in_msg.Dirty;
+ APPEND_TRANSITION_COMMENT(in_msg.Sender);
}
}
}
}
+ action(jd_forwardDmaRequestToLocalOwner, "jd", desc="Forward dma request to local owner") {
+ peek(requestNetwork_in, RequestMsg) {
+ enqueue( localRequestNetwork_out, RequestMsg, latency=response_latency ) {
+ out_msg.Address := in_msg.Address;
+ out_msg.Type := in_msg.Type;
+ out_msg.Requestor := in_msg.Requestor;
+ out_msg.RequestorMachine := in_msg.RequestorMachine;
+ out_msg.Destination.add(getLocalOwner(cache_entry, in_msg.Address));
+ out_msg.Type := in_msg.Type;
+ out_msg.MessageSize := MessageSizeType:Forwarded_Control;
+ out_msg.Acks := 0 - 1;
+ }
+ }
+ }
+
action(k_forwardLocalGETSToLocalSharer, "k", desc="Forward local request to local sharer/owner") {
peek(L1requestNetwork_in, RequestMsg) {
responseNetwork_in.recycle();
}
+ action(da_sendDmaAckUnblock, "da", desc="Send dma ack to global directory") {
+ enqueue(responseNetwork_out, ResponseMsg, latency=response_latency) {
+ out_msg.Address := address;
+ out_msg.Type := CoherenceResponseType:DMA_ACK;
+ out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.Sender := machineID;
+ out_msg.SenderMachine := MachineType:L2Cache;
+ out_msg.MessageSize := MessageSizeType:Unblock_Control;
+ }
+ }
+
//*****************************************************
// TRANSITIONS
//*****************************************************
- transition({II, 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, IGMLS, IGMO, IGMIO, OGMIO, IGMIOF, OGMIOF, MM, SS, OO, OI, MI, MII, OLSI, ILSI, SLSS, OLSS, OLSF, IGMIOFS}, {L1_PUTO, L1_PUTS, L1_PUTS_only, L1_PUTX}) {
+ transition({II, 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, IGMLS, IGMO, IGMIO, OGMIO, IGMIOF, OGMIOF, MM, SS, OO, OI, MI, MII, OLSI, ILSI, SLSS, OLSS, OLSF, IGMIOFS, ILOSD, ILOSXD, ILOD, ILXD, ILOXD}, {L1_PUTO, L1_PUTS, L1_PUTS_only, L1_PUTX}) {
zz_recycleL1RequestQueue;
}
- transition({II, 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, IGMLS, IGMO, IGMIO, OGMIO, IGMIOF, OGMIOF, MM, SS, OO, OI, MI, MII, OLSI, ILSI, SLSS, OLSS, OLSF, IGMIOFS}, {L1_GETX, L1_GETS}) {
+ transition({II, 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, IGMLS, IGMO, IGMIO, OGMIO, IGMIOF, OGMIOF, MM, SS, OO, OI, MI, MII, OLSI, ILSI, SLSS, OLSS, OLSF, IGMIOFS, ILOSD, ILOSXD, ILOD, ILXD, ILOXD}, {L1_GETX, L1_GETS}) {
zz_recycleL1RequestQueue;
}
- transition({IFGX, IFGS, ISFGS, IFGXX, IFLXO, OFGX, ILOW, ILOXW, ILOSW, ILOSXW, SLSW, OLSW, ILSW, IW, ILXW, OW, SW, OXW, OLSXW, IFLS, IFLO, IFLOX, IFLOXX, IFLOSX,OLSXS, IGS, IGM, IGMLS, IGMO, MM, SS, OO, OI, MI, MII, OLSI, ILSI, SLSS, OLSS, OLSF, IGMIOFS}, L2_Replacement) {
+ transition({IFGX, IFGS, ISFGS, IFGXX, IFLXO, OFGX, ILOW, ILOXW, ILOSW, ILOSXW, SLSW, OLSW, ILSW, IW, ILXW, OW, SW, OXW, OLSXW, IFLS, IFLO, IFLOX, IFLOXX, IFLOSX,OLSXS, IGS, IGM, IGMLS, IGMO, MM, SS, OO, OI, MI, MII, OLSI, ILSI, SLSS, OLSS, OLSF, IGMIOFS, ILOSD, ILOSXD, ILOD, ILXD, ILOXD}, L2_Replacement) {
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, IGS, IGM, MM, SS, OO, SLSS, OLSS, OLSF, IGMIOFS}, {Fwd_GETX, Fwd_GETS, Fwd_DMA}) {
+ 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, ILOSD, ILOSXD, ILOD, ILXD, ILOXD}, {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}) {
+ transition({OGMIO, IGMIO, IGMO}, Fwd_DMA) {
zz_recycleRequestQueue;
}
- transition({IGM, IGS}, {Own_GETX}) {
+ 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, ILOSD, ILOSXD, ILOD, ILXD, ILOXD}, {Inv}) {
+ zz_recycleRequestQueue;
+ }
+
+ transition({IGM, IGS, ILOSD, ILOSXD, ILOD, ILXD, ILOXD}, {Own_GETX}) {
zz_recycleRequestQueue;
}
m_popRequestQueue;
}
- transition({ILOS, ILOSX}, Fwd_DMA) {
+ transition(ILOS, Fwd_DMA, ILOSD) {
+ i_allocateTBE;
+ jd_forwardDmaRequestToLocalOwner;
+ m_popRequestQueue;
+ }
+
+ transition(ILOSD, DmaAck, ILOS) {
+ s_deallocateTBE;
+ da_sendDmaAckUnblock;
+ n_popResponseQueue;
+ }
+
+ transition(ILOSX, Fwd_DMA, ILOSXD) {
i_allocateTBE;
t_recordFwdSID;
- j_forwardGlobalRequestToLocalOwner;
+ jd_forwardDmaRequestToLocalOwner;
m_popRequestQueue;
}
- transition({ILO, ILX, ILOX}, Fwd_DMA) {
+ transition(ILOSXD, DmaAck, ILOSX) {
+ s_deallocateTBE;
+ da_sendDmaAckUnblock;
+ n_popResponseQueue;
+ }
+
+ transition(ILO, Fwd_DMA, ILOD) {
i_allocateTBE;
t_recordFwdSID;
- j_forwardGlobalRequestToLocalOwner;
+ jd_forwardDmaRequestToLocalOwner;
m_popRequestQueue;
}
-
+
+ transition(ILOD, DmaAck, ILO) {
+ s_deallocateTBE;
+ da_sendDmaAckUnblock;
+ n_popResponseQueue;
+ }
+
+ transition(ILX, Fwd_DMA, ILXD) {
+ i_allocateTBE;
+ t_recordFwdSID;
+ jd_forwardDmaRequestToLocalOwner;
+ m_popRequestQueue;
+ }
+
+ transition(ILXD, DmaAck, ILX) {
+ s_deallocateTBE;
+ da_sendDmaAckUnblock;
+ n_popResponseQueue;
+ }
+
+ transition(ILOX, Fwd_DMA, ILOXD) {
+ i_allocateTBE;
+ t_recordFwdSID;
+ jd_forwardDmaRequestToLocalOwner;
+ m_popRequestQueue;
+ }
+
+ transition(ILOXD, DmaAck, ILOX) {
+ s_deallocateTBE;
+ da_sendDmaAckUnblock;
+ n_popResponseQueue;
+ }
+
transition({ILOS, ILOSX, ILO, ILX, ILOX, ILXW}, Data) {
i_copyDataToTBE;
c_sendDataFromTBEToFwdGETS;
m_popRequestQueue;
}
- transition({O, OLS}, {Fwd_GETS, Fwd_DMA}) {
+ transition({O, OLS}, Fwd_GETS) {
+ dd_sendDataToFwdGETS;
+ m_popRequestQueue;
+ }
+
+ transition({O, OLS}, Fwd_DMA) {
dd_sendDataToFwdGETS;
+ da_sendDmaAckUnblock;
m_popRequestQueue;
}
transition(OLSX, Fwd_DMA) {
dd_sendDataToFwdGETS;
+ da_sendDmaAckUnblock;
m_popRequestQueue;
}
transition(M, Fwd_DMA) {
dd_sendExclusiveDataToFwdGETS;
+ da_sendDmaAckUnblock;
m_popRequestQueue;
}
o_popL1RequestQueue;
}
- transition(OGMIO, {Fwd_GETS, Fwd_DMA}) {
+ transition(OGMIO, Fwd_GETS) {
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, Fwd_DMA}) {
+ transition(IGMO, Fwd_GETS) {
t_recordFwdSID;
c_sendDataFromTBEToFwdGETS;
m_popRequestQueue;
n_popTriggerQueue;
}
- transition(OLSI, {Fwd_GETS, Fwd_DMA}) {
+ transition(OLSI, Fwd_GETS) {
t_recordFwdSID;
c_sendDataFromTBEToFwdGETS;
m_popRequestQueue;
}
- transition({MI, OI}, {Fwd_GETS, Fwd_DMA}, OI) {
+ transition({MI, OI}, Fwd_GETS, OI) {
t_recordFwdSID;
c_sendDataFromTBEToFwdGETS;
m_popRequestQueue;
}
+ transition({MI, OI}, Fwd_DMA, OI) {
+ cd_sendDataFromTBEToFwdDma;
+ da_sendDmaAckUnblock;
+ m_popRequestQueue;
+ }
+
+ transition(OLSI, Fwd_DMA) {
+ cd_sendDataFromTBEToFwdDma;
+ da_sendDmaAckUnblock;
+ m_popRequestQueue;
+ }
+
transition({MI, OI}, Fwd_GETX, MII) {
t_recordFwdXID;
c_sendDataFromTBEToFwdGETX;
XI_M, AccessPermission:Busy, desc="In a stable state, going to I, waiting for the memory controller";
XI_U, AccessPermission:Busy, desc="In a stable state, going to I, waiting for an unblock";
OI_D, AccessPermission:Busy, desc="In O, going to I, waiting for data";
+
+ OD, AccessPermission:Busy, desc="In O, waiting for dma ack from L2";
+ MD, AccessPermission:Busy, desc="In M, waiting for dma ack from L2";
}
// Events
Memory_Ack, desc="Writeback Ack from memory arrives";
DMA_READ, desc="DMA Read";
DMA_WRITE, desc="DMA Write";
+ DMA_ACK, desc="DMA Ack";
Data, desc="Data to directory";
}
} else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) {
trigger(Event:Data, in_msg.Address,
TBEs[in_msg.Address]);
+ } else if (in_msg.Type == CoherenceResponseType:DMA_ACK) {
+ trigger(Event:DMA_ACK, in_msg.Address,
+ TBEs[in_msg.Address]);
} else {
error("Invalid message");
}
out_msg.Address := address;
out_msg.Type := CoherenceRequestType:WB_NACK;
out_msg.Requestor := in_msg.Requestor;
+ out_msg.RequestorMachine := MachineType:Directory;
out_msg.Destination.add(in_msg.Requestor);
out_msg.MessageSize := MessageSizeType:Writeback_Control;
}
out_msg.Address := address;
out_msg.Type := in_msg.Type;
out_msg.Requestor := in_msg.Requestor;
+ out_msg.RequestorMachine := machineIDToMachineType(in_msg.Requestor);
out_msg.Destination.addNetDest(getDirectoryEntry(in_msg.Address).Owner);
out_msg.Acks := getDirectoryEntry(address).Sharers.count();
if (getDirectoryEntry(address).Sharers.isElement(in_msg.Requestor)) {
out_msg.Address := address;
out_msg.Type := in_msg.Type;
out_msg.Requestor := machineID;
+ out_msg.RequestorMachine := machineIDToMachineType(in_msg.Requestor);
out_msg.Destination.addNetDest(getDirectoryEntry(in_msg.Address).Owner);
out_msg.Acks := getDirectoryEntry(address).Sharers.count();
if (getDirectoryEntry(address).Sharers.isElement(in_msg.Requestor)) {
out_msg.Address := address;
out_msg.Type := CoherenceRequestType:INV;
out_msg.Requestor := in_msg.Requestor;
+ out_msg.RequestorMachine := machineIDToMachineType(in_msg.Requestor);
// out_msg.Destination := getDirectoryEntry(in_msg.Address).Sharers;
out_msg.Destination.addNetDest(getDirectoryEntry(in_msg.Address).Sharers);
out_msg.Destination.remove(in_msg.Requestor);
i_popIncomingRequestQueue;
}
- transition(S, DMA_READ, S) {
+ transition(S, DMA_READ) {
//qf_queueMemoryFetchRequest;
p_fwdDataToDMA;
//g_sendInvalidations; // the DMA will collect the invalidations then send an Unblock Exclusive
i_popIncomingRequestQueue;
}
- transition(O, DMA_READ, O) {
+ transition(O, DMA_READ, OD) {
f_forwardRequest; // this will cause the data to go to DMA directly
//g_sendInvalidations; // this will cause acks to be sent to the DMA
i_popIncomingRequestQueue;
}
+ transition(OD, DMA_ACK, O) {
+ j_popIncomingUnblockQueue;
+ }
+
transition({O,M}, DMA_WRITE, OI_D) {
f_forwardRequestDirIsRequestor; // need the modified data before we can proceed
g_sendInvalidations; // these go to the DMA Controller
}
// no exclusive unblock will show up to the directory
- transition(M, DMA_READ, M) {
+ transition(M, DMA_READ, MD) {
f_forwardRequest; // this will cause the data to go to DMA directly
i_popIncomingRequestQueue;
}
+ transition(MD, DMA_ACK, M) {
+ j_popIncomingUnblockQueue;
+ }
+
transition(M, GETS, MO) {
f_forwardRequest;
i_popIncomingRequestQueue;
}
- transition({MM, MO, MI, MIS, OS, OSS, XI_M, XI_U, OI_D}, {GETS, GETX, PUTO, PUTO_SHARERS, PUTX, DMA_READ, DMA_WRITE}) {
+ transition({MM, MO, MI, MIS, OS, OSS, XI_M, XI_U, OI_D, OD, MD}, {GETS, GETX, PUTO, PUTO_SHARERS, PUTX, DMA_READ, DMA_WRITE}) {
zz_recycleRequest;
}