* Brad Beckmann
*/
-machine({L1Cache, L2Cache}, "AMD Hammer-like protocol")
+machine(MachineType:L1Cache, "AMD Hammer-like protocol")
: Sequencer * sequencer;
CacheMemory * L1Icache;
CacheMemory * L1Dcache;
OI, AccessPermission:Busy, "OI", desc="Issued PutO, waiting for ack";
MI, AccessPermission:Busy, "MI", desc="Issued PutX, waiting for ack";
II, AccessPermission:Busy, "II", desc="Issued PutX/O, saw Other_GETS or Other_GETX, waiting for ack";
- IT, AccessPermission:Busy, "IT", desc="Invalid block transferring to L1";
ST, AccessPermission:Busy, "ST", desc="S block transferring to L1";
OT, AccessPermission:Busy, "OT", desc="O block transferring to L1";
MT, AccessPermission:Busy, "MT", desc="M block transferring to L1";
void wakeUpAllBuffers();
void wakeUpBuffers(Addr a);
Cycles curCycle();
+ MachineID mapAddressToMachine(Addr addr, MachineType mtype);
Entry getCacheEntry(Addr address), return_by_pointer="yes" {
Entry L2cache_entry := static_cast(Entry, "pointer", L2cache.lookup(address));
out_msg.addr := address;
out_msg.Type := CoherenceRequestType:GETS;
out_msg.Requestor := machineID;
- out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
out_msg.MessageSize := MessageSizeType:Request_Control;
out_msg.InitialRequestTime := curCycle();
out_msg.addr := address;
out_msg.Type := CoherenceRequestType:GETX;
out_msg.Requestor := machineID;
- out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
out_msg.MessageSize := MessageSizeType:Request_Control;
out_msg.InitialRequestTime := curCycle();
out_msg.addr := address;
out_msg.Type := CoherenceRequestType:GETX;
out_msg.Requestor := machineID;
- out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
out_msg.MessageSize := MessageSizeType:Request_Control;
out_msg.InitialRequestTime := curCycle();
}
out_msg.addr := address;
out_msg.Type := CoherenceRequestType:GETF;
out_msg.Requestor := machineID;
- out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
out_msg.MessageSize := MessageSizeType:Request_Control;
out_msg.InitialRequestTime := curCycle();
out_msg.addr := address;
out_msg.Type := CoherenceRequestType:PUT;
out_msg.Requestor := machineID;
- out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
out_msg.MessageSize := MessageSizeType:Writeback_Control;
}
}
out_msg.addr := address;
out_msg.Type := CoherenceRequestType:PUTF;
out_msg.Requestor := machineID;
- out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
out_msg.MessageSize := MessageSizeType:Writeback_Control;
}
}
out_msg.addr := address;
out_msg.Type := CoherenceResponseType:UNBLOCK;
out_msg.Sender := machineID;
- out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
out_msg.MessageSize := MessageSizeType:Unblock_Control;
}
}
out_msg.addr := address;
out_msg.Type := CoherenceResponseType:UNBLOCKM;
out_msg.Sender := machineID;
- out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
out_msg.MessageSize := MessageSizeType:Unblock_Control;
}
}
out_msg.Type := CoherenceResponseType:UNBLOCKS;
out_msg.Sender := machineID;
out_msg.CurOwner := tbe.CurOwner;
- out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
out_msg.MessageSize := MessageSizeType:Unblock_Control;
}
}
assert(is_valid(tbe));
out_msg.addr := address;
out_msg.Sender := machineID;
- out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
out_msg.Dirty := tbe.Dirty;
if (tbe.Dirty) {
out_msg.Type := CoherenceResponseType:WB_DIRTY;
assert(is_valid(tbe));
out_msg.addr := address;
out_msg.Sender := machineID;
- out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
out_msg.DataBlk := tbe.DataBlk;
out_msg.Dirty := tbe.Dirty;
if (tbe.Dirty) {
unset_cache_entry();
}
+ action(gr_deallocateCacheBlock, "\gr", desc="Deallocate an L1 or L2 cache block.") {
+ if (L1Dcache.isTagPresent(address)) {
+ L1Dcache.deallocate(address);
+ }
+ else if (L1Icache.isTagPresent(address)){
+ L1Icache.deallocate(address);
+ }
+ else {
+ assert(L2cache.isTagPresent(address));
+ L2cache.deallocate(address);
+ }
+ unset_cache_entry();
+ }
+
action(forward_eviction_to_cpu, "\cc", desc="sends eviction information to the processor") {
if (send_evictions) {
- DPRINTF(RubySlicc, "Sending invalidation for %s to the CPU\n", address);
+ DPRINTF(RubySlicc, "Sending invalidation for %#x to the CPU\n", address);
sequencer.evictionCallback(address);
}
}
//*****************************************************
// Transitions for Load/Store/L2_Replacement from transient states
- transition({IM, IM_F, MM_WF, SM, SM_F, ISM, ISM_F, OM, OM_F, IS, SS, OI, MI, II, IT, ST, OT, MT, MMT}, {Store, L2_Replacement}) {
+ transition({IM, IM_F, MM_WF, SM, SM_F, ISM, ISM_F, OM, OM_F, IS, SS, OI, MI, II, ST, OT, MT, MMT}, {Store, L2_Replacement}) {
zz_stallAndWaitMandatoryQueue;
}
zz_stallAndWaitMandatoryQueue;
}
- transition({IM, IS, OI, MI, II, IT, ST, OT, MT, MMT, MI_F, MM_F, OM_F, IM_F, ISM_F, SM_F, MM_WF}, {Load, Ifetch}) {
+ transition({IM, IS, OI, MI, II, ST, OT, MT, MMT, MI_F, MM_F, OM_F, IM_F, ISM_F, SM_F, MM_WF}, {Load, Ifetch}) {
zz_stallAndWaitMandatoryQueue;
}
- transition({IM, SM, ISM, OM, IS, SS, MM_W, M_W, OI, MI, II, IT, ST, OT, MT, MMT, IM_F, SM_F, ISM_F, OM_F, MM_WF, MI_F, MM_F, IR, SR, OR, MR, MMR}, L1_to_L2) {
+ transition({IM, SM, ISM, OM, IS, SS, MM_W, M_W, OI, MI, II, ST, OT, MT, MMT, IM_F, SM_F, ISM_F, OM_F, MM_WF, MI_F, MM_F, IR, SR, OR, MR, MMR}, L1_to_L2) {
zz_stallAndWaitMandatoryQueue;
}
zz_stallAndWaitMandatoryQueue;
}
- transition({IT, ST, OT, MT, MMT}, {Other_GETX, NC_DMA_GETS, Other_GETS, Merged_GETS, Other_GETS_No_Mig, Invalidate, Flush_line}) {
+ transition({ST, OT, MT, MMT}, {Other_GETX, NC_DMA_GETS, Other_GETS, Merged_GETS, Other_GETS_No_Mig, Invalidate, Flush_line}) {
z_stall;
}
}
// Transitions moving data between the L1 and L2 caches
- transition({I, S, O, M, MM}, L1_to_L2) {
+ transition({S, O, M, MM}, L1_to_L2) {
i_allocateTBE;
gg_deallocateL1CacheBlock;
vv_allocateL2CacheBlock;
s_deallocateTBE;
}
- transition(I, Trigger_L2_to_L1D, IT) {
- i_allocateTBE;
- rr_deallocateL2CacheBlock;
- ii_allocateL1DCacheBlock;
- nb_copyFromTBEToL1; // Not really needed for state I
- s_deallocateTBE;
- zz_stallAndWaitMandatoryQueue;
- ll_L2toL1Transfer;
- }
-
transition(S, Trigger_L2_to_L1D, ST) {
i_allocateTBE;
rr_deallocateL2CacheBlock;
ll_L2toL1Transfer;
}
- transition(I, Trigger_L2_to_L1I, IT) {
- i_allocateTBE;
- rr_deallocateL2CacheBlock;
- jj_allocateL1ICacheBlock;
- nb_copyFromTBEToL1;
- s_deallocateTBE;
- zz_stallAndWaitMandatoryQueue;
- ll_L2toL1Transfer;
- }
-
transition(S, Trigger_L2_to_L1I, ST) {
i_allocateTBE;
rr_deallocateL2CacheBlock;
ll_L2toL1Transfer;
}
- transition(IT, Complete_L2_to_L1, IR) {
- j_popTriggerQueue;
- kd_wakeUpDependents;
- }
-
transition(ST, Complete_L2_to_L1, SR) {
j_popTriggerQueue;
kd_wakeUpDependents;
k_popMandatoryQueue;
}
- transition(I, L2_Replacement) {
- rr_deallocateL2CacheBlock;
- ka_wakeUpAllDependents;
- }
-
transition(I, {Other_GETX, NC_DMA_GETS, Other_GETS, Other_GETS_No_Mig, Invalidate}) {
f_sendAck;
l_popForwardQueue;
transition(S, {Other_GETX, Invalidate}, I) {
f_sendAck;
forward_eviction_to_cpu;
+ gr_deallocateCacheBlock;
l_popForwardQueue;
}
transition(O, {Other_GETX, Invalidate}, I) {
e_sendData;
forward_eviction_to_cpu;
+ gr_deallocateCacheBlock;
l_popForwardQueue;
}
transition(MM, {Other_GETX, Invalidate}, I) {
c_sendExclusiveData;
forward_eviction_to_cpu;
+ gr_deallocateCacheBlock;
l_popForwardQueue;
}
transition(MM, Other_GETS, I) {
c_sendExclusiveData;
forward_eviction_to_cpu;
+ gr_deallocateCacheBlock;
l_popForwardQueue;
}
transition(M, {Other_GETX, Invalidate}, I) {
c_sendExclusiveData;
forward_eviction_to_cpu;
+ gr_deallocateCacheBlock;
l_popForwardQueue;
}