diff -r 523c3adda92d -r 8305ac8ce68c configs/ruby/MOESI_hammer.py --- a/configs/ruby/MOESI_hammer.py Thu Jan 06 15:26:56 2011 -0800 +++ b/configs/ruby/MOESI_hammer.py Thu Jan 06 15:27:17 2011 -0800 @@ -55,7 +55,9 @@ help="allow migratory sharing for atomic only accessed blocks") parser.add_option("--pf-on", action="store_true", help="Hammer: enable Probe Filter") - + parser.add_option("--dir-on", action="store_true", + help="Hammer: enable Full-bit Directory") + def create_system(options, system, piobus, dma_devices): if buildEnv['PROTOCOL'] != 'MOESI_hammer': @@ -165,7 +167,8 @@ options.map_levels), probeFilter = pf, memBuffer = mem_cntrl, - probe_filter_enabled = options.pf_on) + probe_filter_enabled = options.pf_on, + full_bit_dir_enabled = options.dir_on) if options.recycle_latency: dir_cntrl.recycle_latency = options.recycle_latency diff -r 523c3adda92d -r 8305ac8ce68c src/mem/protocol/MOESI_hammer-cache.sm --- a/src/mem/protocol/MOESI_hammer-cache.sm Thu Jan 06 15:26:56 2011 -0800 +++ b/src/mem/protocol/MOESI_hammer-cache.sm Thu Jan 06 15:27:17 2011 -0800 @@ -137,6 +137,7 @@ bool Dirty, desc="Is the data dirty (different than memory)?"; int NumPendingMsgs, desc="Number of acks/data messages that this processor is waiting for"; bool Sharers, desc="On a GetS, did we find any other sharers in the system"; + bool AppliedSilentAcks, default="false", desc="for full-bit dir, does the pending msg count reflect the silent acks"; MachineID LastResponder, desc="last machine to send a response for this request"; MachineID CurOwner, desc="current owner of the block, used for UnblockS responses"; Time InitialRequestTime, default="0", desc="time the initial requests was sent from the L1Cache"; @@ -467,6 +468,7 @@ } else { out_msg.Acks := 2; } + out_msg.SilentAcks := in_msg.SilentAcks; out_msg.MessageSize := MessageSizeType:Response_Data; out_msg.InitialRequestTime := in_msg.InitialRequestTime; out_msg.ForwardRequestTime := in_msg.ForwardRequestTime; @@ -498,6 +500,7 @@ } else { out_msg.Acks := 2; } + out_msg.SilentAcks := in_msg.SilentAcks; out_msg.MessageSize := MessageSizeType:Response_Data; out_msg.InitialRequestTime := in_msg.InitialRequestTime; out_msg.ForwardRequestTime := in_msg.ForwardRequestTime; @@ -520,6 +523,7 @@ } else { out_msg.Acks := 2; } + out_msg.SilentAcks := in_msg.SilentAcks; out_msg.MessageSize := MessageSizeType:Response_Data; out_msg.InitialRequestTime := in_msg.InitialRequestTime; out_msg.ForwardRequestTime := in_msg.ForwardRequestTime; @@ -538,6 +542,7 @@ DPRINTF(RubySlicc, "%s\n", out_msg.DataBlk); out_msg.Dirty := getCacheEntry(address).Dirty; out_msg.Acks := machineCount(MachineType:L1Cache); + out_msg.SilentAcks := in_msg.SilentAcks; out_msg.MessageSize := MessageSizeType:Response_Data; out_msg.InitialRequestTime := in_msg.InitialRequestTime; out_msg.ForwardRequestTime := in_msg.ForwardRequestTime; @@ -553,6 +558,7 @@ out_msg.Sender := machineID; out_msg.Destination.add(in_msg.Requestor); out_msg.Acks := 1; + out_msg.SilentAcks := in_msg.SilentAcks; assert(in_msg.DirectedProbe == false); out_msg.MessageSize := MessageSizeType:Response_Control; out_msg.InitialRequestTime := in_msg.InitialRequestTime; @@ -569,6 +575,7 @@ out_msg.Sender := machineID; out_msg.Destination.add(in_msg.Requestor); out_msg.Acks := 1; + out_msg.SilentAcks := in_msg.SilentAcks; assert(in_msg.DirectedProbe == false); out_msg.MessageSize := MessageSizeType:Response_Control; out_msg.InitialRequestTime := in_msg.InitialRequestTime; @@ -708,9 +715,17 @@ action(m_decrementNumberOfMessages, "m", desc="Decrement the number of messages for which we're waiting") { peek(responseToCache_in, ResponseMsg) { assert(in_msg.Acks > 0); + DPRINTF(RubySlicc, "Sender = %s\n", in_msg.Sender); + DPRINTF(RubySlicc, "SilentAcks = %d\n", in_msg.SilentAcks); + if (TBEs[address].AppliedSilentAcks == false) { + TBEs[address].NumPendingMsgs := TBEs[address].NumPendingMsgs - in_msg.SilentAcks; + TBEs[address].AppliedSilentAcks := true; + } DPRINTF(RubySlicc, "%d\n", TBEs[address].NumPendingMsgs); TBEs[address].NumPendingMsgs := TBEs[address].NumPendingMsgs - in_msg.Acks; DPRINTF(RubySlicc, "%d\n", TBEs[address].NumPendingMsgs); + APPEND_TRANSITION_COMMENT(TBEs[address].NumPendingMsgs); + APPEND_TRANSITION_COMMENT(in_msg.Sender); TBEs[address].LastResponder := in_msg.Sender; if (TBEs[address].InitialRequestTime != zero_time() && in_msg.InitialRequestTime != zero_time()) { assert(TBEs[address].InitialRequestTime == in_msg.InitialRequestTime); @@ -769,6 +784,7 @@ action(q_sendDataFromTBEToCache, "q", desc="Send data from TBE to cache") { peek(forwardToCache_in, RequestMsg) { + assert(in_msg.Requestor != machineID); enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA; @@ -782,6 +798,7 @@ } else { out_msg.Acks := 2; } + out_msg.SilentAcks := in_msg.SilentAcks; out_msg.MessageSize := MessageSizeType:Response_Data; out_msg.InitialRequestTime := in_msg.InitialRequestTime; out_msg.ForwardRequestTime := in_msg.ForwardRequestTime; @@ -800,6 +817,7 @@ out_msg.DataBlk := TBEs[address].DataBlk; out_msg.Dirty := TBEs[address].Dirty; out_msg.Acks := machineCount(MachineType:L1Cache); + out_msg.SilentAcks := in_msg.SilentAcks; out_msg.MessageSize := MessageSizeType:Response_Data; out_msg.InitialRequestTime := in_msg.InitialRequestTime; out_msg.ForwardRequestTime := in_msg.ForwardRequestTime; @@ -1302,7 +1320,7 @@ n_popResponseQueue; } - transition(SM, Data, ISM) { + transition(SM, {Data, Exclusive_Data}, ISM) { v_writeDataToCacheVerify; m_decrementNumberOfMessages; o_checkForCompletion; diff -r 523c3adda92d -r 8305ac8ce68c src/mem/protocol/MOESI_hammer-dir.sm --- a/src/mem/protocol/MOESI_hammer-dir.sm Thu Jan 06 15:26:56 2011 -0800 +++ b/src/mem/protocol/MOESI_hammer-dir.sm Thu Jan 06 15:27:17 2011 -0800 @@ -38,7 +38,8 @@ CacheMemory * probeFilter, MemoryControl * memBuffer, int memory_controller_latency = 2, - bool probe_filter_enabled = false + bool probe_filter_enabled = false, + bool full_bit_dir_enabled = false { MessageBuffer forwardFromDir, network="To", virtual_network="3", ordered="false"; @@ -140,6 +141,7 @@ State PfState, desc="Directory state"; MachineID Owner, desc="Owner node"; DataBlock DataBlk, desc="data for the block"; + Set Sharers, desc="sharing vector for full bit directory"; } // TBE entries for DMA requests @@ -148,6 +150,7 @@ State TBEState, desc="Transient State"; CoherenceResponseType ResponseType, desc="The type for the subsequent response message"; int Acks, default="0", desc="The number of acks that the waiting response represents"; + int SilentAcks, default="0", desc="The number of silent acks associated with this transaction"; DataBlock DmaDataBlk, desc="DMA Data to be written. Partial blocks need to merged with system memory"; DataBlock DataBlk, desc="The current view of system memory"; int Len, desc="..."; @@ -168,6 +171,8 @@ // ** OBJECTS ** + Set fwd_set; + TBETable TBEs, template_hack=""; Entry getDirectoryEntry(Address addr), return_by_ref="yes" { @@ -182,7 +187,7 @@ if (TBEs.isPresent(addr)) { return TBEs[addr].TBEState; } else { - if (probe_filter_enabled) { + if (probe_filter_enabled || full_bit_dir_enabled) { if (probeFilter.isTagPresent(addr)) { assert(getPfEntry(addr).PfState == getDirectoryEntry(addr).DirectoryState); } else { @@ -197,7 +202,7 @@ if (TBEs.isPresent(addr)) { TBEs[addr].TBEState := state; } - if (probe_filter_enabled) { + if (probe_filter_enabled || full_bit_dir_enabled) { if (probeFilter.isTagPresent(addr)) { getPfEntry(addr).PfState := state; } @@ -324,7 +329,7 @@ if (in_msg.Type == CoherenceRequestType:PUT) { trigger(Event:PUT, in_msg.Address); } else { - if (probe_filter_enabled) { + if (probe_filter_enabled || full_bit_dir_enabled) { if (probeFilter.isTagPresent(in_msg.Address)) { trigger(cache_request_to_event(in_msg.Type), in_msg.Address); } else { @@ -359,26 +364,44 @@ // Actions action(r_setMRU, "\rr", desc="manually set the MRU bit for pf entry" ) { - if (probe_filter_enabled) { + if (probe_filter_enabled || full_bit_dir_enabled) { assert(probeFilter.isTagPresent(address)); probeFilter.setMRU(address); } } action(auno_assertUnblockerNotOwner, "auno", desc="assert unblocker not owner") { - if (probe_filter_enabled) { + if (probe_filter_enabled || full_bit_dir_enabled) { assert(probeFilter.isTagPresent(address)); peek(unblockNetwork_in, ResponseMsg) { assert(getPfEntry(address).Owner != in_msg.Sender); + if (full_bit_dir_enabled) { + assert(getPfEntry(address).Sharers.isElement(machineIDToNodeID(in_msg.Sender)) == false); + } } } } action(uo_updateOwnerIfPf, "uo", desc="update owner") { - if (probe_filter_enabled) { + if (probe_filter_enabled || full_bit_dir_enabled) { assert(probeFilter.isTagPresent(address)); peek(unblockNetwork_in, ResponseMsg) { getPfEntry(address).Owner := in_msg.Sender; + if (full_bit_dir_enabled) { + getPfEntry(address).Sharers.clear(); + getPfEntry(address).Sharers.add(machineIDToNodeID(in_msg.Sender)); + APPEND_TRANSITION_COMMENT(getPfEntry(address).Sharers); + DPRINTF(RubySlicc, "Sharers = %d\n", getPfEntry(address).Sharers); + } + } + } + } + + action(us_updateSharerIfFBD, "us", desc="update sharer if full-bit directory") { + if (full_bit_dir_enabled) { + assert(probeFilter.isTagPresent(address)); + peek(unblockNetwork_in, ResponseMsg) { + getPfEntry(address).Sharers.add(machineIDToNodeID(in_msg.Sender)); } } } @@ -408,22 +431,24 @@ } action(pfa_probeFilterAllocate, "pfa", desc="Allocate ProbeFilterEntry") { - if (probe_filter_enabled) { + if (probe_filter_enabled || full_bit_dir_enabled) { peek(requestQueue_in, RequestMsg) { probeFilter.allocate(address, new PfEntry); getPfEntry(in_msg.Address).Owner := in_msg.Requestor; + getPfEntry(in_msg.Address).Sharers.setSize(machineCount(MachineType:L1Cache)); + getPfEntry(in_msg.Address).Sharers.add(machineIDToNodeID(in_msg.Requestor)); } } } action(pfd_probeFilterDeallocate, "pfd", desc="Deallocate ProbeFilterEntry") { - if (probe_filter_enabled) { + if (probe_filter_enabled || full_bit_dir_enabled) { probeFilter.deallocate(address); } } action(ppfd_possibleProbeFilterDeallocate, "ppfd", desc="Deallocate ProbeFilterEntry") { - if (probe_filter_enabled && probeFilter.isTagPresent(address)) { + if ((probe_filter_enabled || full_bit_dir_enabled) && probeFilter.isTagPresent(address)) { probeFilter.deallocate(address); } } @@ -457,7 +482,11 @@ } action(pa_setPendingMsgsToAll, "pa", desc="set pending msgs to all") { - TBEs[address].NumPendingMsgs := machineCount(MachineType:L1Cache); + if (full_bit_dir_enabled) { + TBEs[address].NumPendingMsgs := getPfEntry(address).Sharers.count(); + } else { + TBEs[address].NumPendingMsgs := machineCount(MachineType:L1Cache); + } } action(po_setPendingMsgsToOne, "po", desc="set pending msgs to one") { @@ -469,12 +498,32 @@ } action(sa_setAcksToOne, "sa", desc="Forwarded request, set the ack amount to one") { - TBEs[address].Acks := 1; + peek(requestQueue_in, RequestMsg) { + if (full_bit_dir_enabled) { + // + // If we are using the full-bit directory and no sharers exists beyond + // the requestor, then we must set the ack number to all, not one + // + fwd_set := getPfEntry(address).Sharers; + fwd_set.remove(machineIDToNodeID(in_msg.Requestor)); + if (fwd_set.count() > 0) { + TBEs[address].Acks := 1; + TBEs[address].SilentAcks := machineCount(MachineType:L1Cache) - fwd_set.count(); + TBEs[address].SilentAcks := TBEs[address].SilentAcks - 1; + } else { + TBEs[address].Acks := machineCount(MachineType:L1Cache); + TBEs[address].SilentAcks := 0; + } + } else { + TBEs[address].Acks := 1; + } + } } action(saa_setAcksToAllIfPF, "saa", desc="Non-forwarded request, set the ack amount to all") { - if (probe_filter_enabled) { + if (probe_filter_enabled || full_bit_dir_enabled) { TBEs[address].Acks := machineCount(MachineType:L1Cache); + TBEs[address].SilentAcks := 0; } else { TBEs[address].Acks := 1; } @@ -543,14 +592,14 @@ } action(spa_setPendingAcksToZeroIfPF, "spa", desc="if probe filter, no need to wait for acks") { - if (probe_filter_enabled) { + if (probe_filter_enabled || full_bit_dir_enabled) { TBEs[address].NumPendingMsgs := 0; } } action(sc_signalCompletionIfPF, "sc", desc="indicate that we should skip waiting for cpu acks") { if (TBEs[address].NumPendingMsgs == 0) { - assert(probe_filter_enabled); + assert(probe_filter_enabled || full_bit_dir_enabled); enqueue(triggerQueue_out, TriggerMsg) { out_msg.Address := address; out_msg.Type := TriggerType:ALL_ACKS_NO_SHARERS; @@ -569,6 +618,7 @@ DPRINTF(RubySlicc, "%s\n", out_msg.DataBlk); out_msg.Dirty := false; // By definition, the block is now clean out_msg.Acks := TBEs[address].Acks; + out_msg.SilentAcks := TBEs[address].SilentAcks; DPRINTF(RubySlicc, "%d\n", out_msg.Acks); assert(out_msg.Acks > 0); out_msg.MessageSize := MessageSizeType:Response_Data; @@ -628,7 +678,17 @@ action(r_recordDataInTBE, "rt", desc="Record Data in TBE") { peek(requestQueue_in, RequestMsg) { - TBEs[address].ResponseType := CoherenceResponseType:DATA; + if (full_bit_dir_enabled) { + fwd_set := getPfEntry(address).Sharers; + fwd_set.remove(machineIDToNodeID(in_msg.Requestor)); + if (fwd_set.count() > 0) { + TBEs[address].ResponseType := CoherenceResponseType:DATA; + } else { + TBEs[address].ResponseType := CoherenceResponseType:DATA_EXCLUSIVE; + } + } else { + TBEs[address].ResponseType := CoherenceResponseType:DATA; + } } } @@ -677,29 +737,62 @@ action(fn_forwardRequestIfNecessary, "fn", desc="Forward requests if necessary") { if ((machineCount(MachineType:L1Cache) > 1) && (TBEs[address].Acks <= 1)) { - peek(requestQueue_in, RequestMsg) { - enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) { - out_msg.Address := address; - out_msg.Type := in_msg.Type; - out_msg.Requestor := in_msg.Requestor; - out_msg.Destination.broadcast(MachineType:L1Cache); // Send to all L1 caches - out_msg.Destination.remove(in_msg.Requestor); // Don't include the original requestor - out_msg.MessageSize := MessageSizeType:Broadcast_Control; - out_msg.InitialRequestTime := in_msg.InitialRequestTime; - out_msg.ForwardRequestTime := get_time(); + if (full_bit_dir_enabled) { + peek(requestQueue_in, RequestMsg) { + fwd_set := getPfEntry(address).Sharers; + fwd_set.remove(machineIDToNodeID(in_msg.Requestor)); + if (fwd_set.count() > 0) { + enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) { + out_msg.Address := address; + out_msg.Type := in_msg.Type; + out_msg.Requestor := in_msg.Requestor; + out_msg.Destination.setNetDest(MachineType:L1Cache, fwd_set); + out_msg.MessageSize := MessageSizeType:Multicast_Control; + out_msg.InitialRequestTime := in_msg.InitialRequestTime; + out_msg.ForwardRequestTime := get_time(); + assert(TBEs[address].SilentAcks > 0); + out_msg.SilentAcks := TBEs[address].SilentAcks; + } + } } + } else { + peek(requestQueue_in, RequestMsg) { + enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) { + out_msg.Address := address; + out_msg.Type := in_msg.Type; + out_msg.Requestor := in_msg.Requestor; + out_msg.Destination.broadcast(MachineType:L1Cache); // Send to all L1 caches + out_msg.Destination.remove(in_msg.Requestor); // Don't include the original requestor + out_msg.MessageSize := MessageSizeType:Broadcast_Control; + out_msg.InitialRequestTime := in_msg.InitialRequestTime; + out_msg.ForwardRequestTime := get_time(); + } + } } } } action(ia_invalidateAllRequest, "ia", desc="invalidate all copies") { if (machineCount(MachineType:L1Cache) > 1) { - enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) { - out_msg.Address := address; - out_msg.Type := CoherenceRequestType:INV; - out_msg.Requestor := machineID; - out_msg.Destination.broadcast(MachineType:L1Cache); // Send to all L1 caches - out_msg.MessageSize := MessageSizeType:Broadcast_Control; + if (full_bit_dir_enabled) { + assert(getPfEntry(address).Sharers.count() > 0); + peek(requestQueue_in, RequestMsg) { + enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) { + out_msg.Address := address; + out_msg.Type := CoherenceRequestType:INV; + out_msg.Requestor := machineID; + out_msg.Destination.setNetDest(MachineType:L1Cache, getPfEntry(address).Sharers); + out_msg.MessageSize := MessageSizeType:Multicast_Control; + } + } + } else { + enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) { + out_msg.Address := address; + out_msg.Type := CoherenceRequestType:INV; + out_msg.Requestor := machineID; + out_msg.Destination.broadcast(MachineType:L1Cache); // Send to all L1 caches + out_msg.MessageSize := MessageSizeType:Broadcast_Control; + } } } } @@ -720,15 +813,33 @@ action(fb_forwardRequestBcast, "fb", desc="Forward requests to all nodes") { if (machineCount(MachineType:L1Cache) > 1) { peek(requestQueue_in, RequestMsg) { - enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) { - out_msg.Address := address; - out_msg.Type := in_msg.Type; - out_msg.Requestor := in_msg.Requestor; - out_msg.Destination.broadcast(MachineType:L1Cache); // Send to all L1 caches - out_msg.Destination.remove(in_msg.Requestor); // Don't include the original requestor - out_msg.MessageSize := MessageSizeType:Broadcast_Control; - out_msg.InitialRequestTime := in_msg.InitialRequestTime; - out_msg.ForwardRequestTime := get_time(); + if (full_bit_dir_enabled) { + fwd_set := getPfEntry(address).Sharers; + fwd_set.remove(machineIDToNodeID(in_msg.Requestor)); + if (fwd_set.count() > 0) { + enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) { + out_msg.Address := address; + out_msg.Type := in_msg.Type; + out_msg.Requestor := in_msg.Requestor; + out_msg.Destination.setNetDest(MachineType:L1Cache, fwd_set); + out_msg.MessageSize := MessageSizeType:Multicast_Control; + out_msg.InitialRequestTime := in_msg.InitialRequestTime; + out_msg.ForwardRequestTime := get_time(); + out_msg.SilentAcks := machineCount(MachineType:L1Cache) - fwd_set.count(); + out_msg.SilentAcks := out_msg.SilentAcks - 1; + } + } + } else { + enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) { + out_msg.Address := address; + out_msg.Type := in_msg.Type; + out_msg.Requestor := in_msg.Requestor; + out_msg.Destination.broadcast(MachineType:L1Cache); // Send to all L1 caches + out_msg.Destination.remove(in_msg.Requestor); // Don't include the original requestor + out_msg.MessageSize := MessageSizeType:Broadcast_Control; + out_msg.InitialRequestTime := in_msg.InitialRequestTime; + out_msg.ForwardRequestTime := get_time(); + } } } } @@ -759,7 +870,7 @@ action(fc_forwardRequestConditionalOwner, "fc", desc="Forward request to one or more nodes") { assert(machineCount(MachineType:L1Cache) > 1); - if (probe_filter_enabled) { + if (probe_filter_enabled || full_bit_dir_enabled) { peek(requestQueue_in, RequestMsg) { enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) { out_msg.Address := address; @@ -910,13 +1021,39 @@ } action(ano_assertNotOwner, "ano", desc="Assert that request is not current owner") { - if (probe_filter_enabled) { + if (probe_filter_enabled || full_bit_dir_enabled) { peek(requestQueue_in, RequestMsg) { assert(getPfEntry(address).Owner != in_msg.Requestor); } } } + action(ans_assertNotSharer, "ans", desc="Assert that request is not a current sharer") { + if (full_bit_dir_enabled) { + peek(requestQueue_in, RequestMsg) { + assert(getPfEntry(address).Sharers.isElement(machineIDToNodeID(in_msg.Requestor)) == false); + } + } + } + + action(rs_removeSharer, "s", desc="remove current sharer") { + if (full_bit_dir_enabled) { + peek(unblockNetwork_in, ResponseMsg) { + assert(getPfEntry(address).Sharers.isElement(machineIDToNodeID(in_msg.Sender))); + getPfEntry(address).Sharers.remove(machineIDToNodeID(in_msg.Sender)); + } + } + } + + action(cs_clearSharers, "cs", desc="clear current sharers") { + if (full_bit_dir_enabled) { + peek(requestQueue_in, RequestMsg) { + getPfEntry(address).Sharers.clear(); + getPfEntry(address).Sharers.add(machineIDToNodeID(in_msg.Requestor)); + } + } + } + action(l_queueMemoryWBRequest, "lq", desc="Write PUTX data to memory") { peek(unblockNetwork_in, ResponseMsg) { enqueue(memQueue_out, MemoryMsg, latency="1") { @@ -1006,6 +1143,7 @@ sa_setAcksToOne; qf_queueMemoryFetchRequest; fb_forwardRequestBcast; + cs_clearSharers; i_popIncomingRequestQueue; } @@ -1068,6 +1206,7 @@ transition(NX, GETX, NO_B) { r_setMRU; fb_forwardRequestBcast; + cs_clearSharers; i_popIncomingRequestQueue; } @@ -1076,12 +1215,14 @@ r_setMRU; ano_assertNotOwner; fc_forwardRequestConditionalOwner; + cs_clearSharers; i_popIncomingRequestQueue; } transition(S, GETX, NO_B) { r_setMRU; fb_forwardRequestBcast; + cs_clearSharers; i_popIncomingRequestQueue; } @@ -1092,7 +1233,15 @@ i_popIncomingRequestQueue; } - transition({NX, NO}, GETS, NO_B) { + transition(NO, GETS, NO_B) { + r_setMRU; + ano_assertNotOwner; + ans_assertNotSharer; + fc_forwardRequestConditionalOwner; + i_popIncomingRequestQueue; + } + + transition(NX, GETS, NO_B) { r_setMRU; ano_assertNotOwner; fc_forwardRequestConditionalOwner; @@ -1140,7 +1289,7 @@ z_stallAndWaitRequest; } - transition({NO_B, NO_B_S, O_B, NO_DR_B_W, NO_DW_B_W, NO_B_W, NO_DR_B_D, + transition({NO_B_X, NO_B, NO_B_S, O_B, NO_DR_B_W, NO_DW_B_W, NO_B_W, NO_DR_B_D, NO_DR_B, O_DR_B, O_B_W, O_DR_B_W, NO_DW_W, NO_B_S_W, NO_W, O_W, WB, WB_E_W, WB_O_W, O_R, S_R, NO_R}, {DMA_READ, DMA_WRITE}) { @@ -1161,17 +1310,20 @@ // unblock responses transition({NO_B, NO_B_X}, UnblockS, NX) { + us_updateSharerIfFBD; k_wakeUpDependents; j_popIncomingUnblockQueue; } transition({NO_B, NO_B_X}, UnblockM, NO) { uo_updateOwnerIfPf; + us_updateSharerIfFBD; k_wakeUpDependents; j_popIncomingUnblockQueue; } transition(NO_B_S, UnblockS, NO_B_S_W) { + us_updateSharerIfFBD; fr_forwardMergeReadRequestsToOwner; sp_setPendingMsgsToMergedSharers; j_popIncomingUnblockQueue; @@ -1185,6 +1337,7 @@ } transition(NO_B_S_W, UnblockS) { + us_updateSharerIfFBD; mu_decrementNumberOfUnblocks; os_checkForMergedGetSCompletion; j_popIncomingUnblockQueue; @@ -1197,6 +1350,14 @@ } transition(O_B, UnblockS, O) { + us_updateSharerIfFBD; + k_wakeUpDependents; + j_popIncomingUnblockQueue; + } + + transition(O_B, UnblockM, NO) { + us_updateSharerIfFBD; + uo_updateOwnerIfPf; k_wakeUpDependents; j_popIncomingUnblockQueue; } @@ -1434,10 +1595,12 @@ } transition(NO_B_W, UnblockS, NO_W) { + us_updateSharerIfFBD; j_popIncomingUnblockQueue; } transition(O_B_W, UnblockS, O_W) { + us_updateSharerIfFBD; j_popIncomingUnblockQueue; } @@ -1456,12 +1619,14 @@ // WB State Transistions transition(WB, Writeback_Dirty, WB_O_W) { l_writeDataToMemory; + rs_removeSharer; l_queueMemoryWBRequest; j_popIncomingUnblockQueue; } transition(WB, Writeback_Exclusive_Dirty, WB_E_W) { l_writeDataToMemory; + rs_removeSharer; l_queueMemoryWBRequest; j_popIncomingUnblockQueue; } @@ -1479,18 +1644,20 @@ transition(WB, Writeback_Clean, O) { ll_checkIncomingWriteback; + rs_removeSharer; k_wakeUpDependents; j_popIncomingUnblockQueue; } transition(WB, Writeback_Exclusive_Clean, E) { ll_checkIncomingWriteback; + rs_removeSharer; pfd_probeFilterDeallocate; k_wakeUpDependents; j_popIncomingUnblockQueue; } - transition(WB, Unblock, NO) { + transition(WB, Unblock, NX) { auno_assertUnblockerNotOwner; k_wakeUpDependents; j_popIncomingUnblockQueue; diff -r 523c3adda92d -r 8305ac8ce68c src/mem/protocol/MOESI_hammer-msg.sm --- a/src/mem/protocol/MOESI_hammer-msg.sm Thu Jan 06 15:26:56 2011 -0800 +++ b/src/mem/protocol/MOESI_hammer-msg.sm Thu Jan 06 15:27:17 2011 -0800 @@ -83,6 +83,7 @@ bool DirectedProbe, default="false", desc="probe filter directed probe"; Time InitialRequestTime, default="0", desc="time the initial requests was sent from the L1Cache"; Time ForwardRequestTime, default="0", desc="time the dir forwarded the request"; + int SilentAcks, default="0", desc="silent acks from the full-bit directory"; } // ResponseMsg (and also unblock requests) @@ -94,10 +95,11 @@ NetDest Destination, desc="Node to whom the data is sent"; DataBlock DataBlk, desc="data for the cache line"; bool Dirty, desc="Is the data dirty (different than memory)?"; - int Acks, desc="How many messages this counts as"; + int Acks, default="0", desc="How many messages this counts as"; MessageSizeType MessageSize, desc="size category of the message"; Time InitialRequestTime, default="0", desc="time the initial requests was sent from the L1Cache"; Time ForwardRequestTime, default="0", desc="time the dir forwarded the request"; + int SilentAcks, default="0", desc="silent acks from the full-bit directory"; } enumeration(DMARequestType, desc="...", default="DMARequestType_NULL") { diff -r 523c3adda92d -r 8305ac8ce68c src/mem/protocol/RubySlicc_Exports.sm --- a/src/mem/protocol/RubySlicc_Exports.sm Thu Jan 06 15:26:56 2011 -0800 +++ b/src/mem/protocol/RubySlicc_Exports.sm Thu Jan 06 15:27:17 2011 -0800 @@ -173,6 +173,7 @@ Writeback_Data, desc="Writeback data"; Writeback_Control, desc="Writeback control"; Broadcast_Control, desc="Broadcast control"; + Multicast_Control, desc="Multicast control"; Forwarded_Control, desc="Forwarded control"; Invalidate_Control, desc="Invalidate control"; Unblock_Control, desc="Unblock control"; diff -r 523c3adda92d -r 8305ac8ce68c src/mem/ruby/network/Network.cc --- a/src/mem/ruby/network/Network.cc Thu Jan 06 15:26:56 2011 -0800 +++ b/src/mem/ruby/network/Network.cc Thu Jan 06 15:27:17 2011 -0800 @@ -73,6 +73,7 @@ case MessageSizeType_Response_Control: case MessageSizeType_Writeback_Control: case MessageSizeType_Broadcast_Control: + case MessageSizeType_Multicast_Control: case MessageSizeType_Forwarded_Control: case MessageSizeType_Invalidate_Control: case MessageSizeType_Unblock_Control: