From 9f9606fb6398a4f3bb38d1461bb7c12956e5e47d Mon Sep 17 00:00:00 2001 From: Timothy Hayes Date: Fri, 18 Oct 2019 16:37:26 +0100 Subject: [PATCH] mem-ruby: MESI_Three_level HTML reference generation fix The SLICC HTML generator does not work without the 'desc' property of the STATES and EVENTS found in the protocol state machine source files. This adds the 'desc' property in MESI_Three_Level to declarations where it was missing and cleans up the text of some existing ones. Issue-on: https://gem5.atlassian.net/browse/GEM5-357 Change-Id: I2d0f8e11889554063fed798e724217963d4a74de Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24256 Reviewed-by: Daniel Carvalho Reviewed-by: Jason Lowe-Power Tested-by: Gem5 Cloud Project GCB service account <345032938727@cloudbuild.gserviceaccount.com> Tested-by: kokoro Maintainer: Jason Lowe-Power --- .../ruby/protocol/MESI_Three_Level-L0cache.sm | 77 ++++++++++++------- .../ruby/protocol/MESI_Three_Level-L1cache.sm | 49 +++++++----- 2 files changed, 78 insertions(+), 48 deletions(-) diff --git a/src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm b/src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm index 84bb0d868..c6697c368 100644 --- a/src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm +++ b/src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm @@ -1,4 +1,16 @@ /* + * Copyright (c) 2020 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2013 Mark D. Hill and David A. Wood * All rights reserved. * @@ -48,43 +60,43 @@ machine(MachineType:L0Cache, "MESI Directory L0 Cache") // Base states // The cache entry has not been allocated. - I, AccessPermission:Invalid; + I, AccessPermission:Invalid, desc="Invalid"; // The cache entry is in shared mode. The processor can read this entry // but it cannot write to it. - S, AccessPermission:Read_Only; + S, AccessPermission:Read_Only, desc="Shared"; // The cache entry is in exclusive mode. The processor can read this // entry. It can write to this entry without informing the directory. // On writing, the entry moves to M state. - E, AccessPermission:Read_Only; + E, AccessPermission:Read_Only, desc="Exclusive"; // The processor has read and write permissions on this entry. - M, AccessPermission:Read_Write; + M, AccessPermission:Read_Write, desc="Modified"; // Transient States // The cache controller has requested an instruction. It will be stored // in the shared state so that the processor can read it. - Inst_IS, AccessPermission:Busy; + Inst_IS, AccessPermission:Busy, desc="Issued GETS, have not seen response yet"; // The cache controller has requested that this entry be fetched in // shared state so that the processor can read it. - IS, AccessPermission:Busy; + IS, AccessPermission:Busy, desc="Issued GETS, have not seen response yet"; // The cache controller has requested that this entry be fetched in // modify state so that the processor can read/write it. - IM, AccessPermission:Busy; + IM, AccessPermission:Busy, desc="Issued GETX, have not seen response yet"; // The cache controller had read permission over the entry. But now the // processor needs to write to it. So, the controller has requested for // write permission. - SM, AccessPermission:Read_Only; + SM, AccessPermission:Read_Only, desc="Issued GETX, have not seen response yet"; } // EVENTS enumeration(Event, desc="Cache events") { - // L0 events + // Events from core Load, desc="Load request from the home processor"; Ifetch, desc="I-fetch request from the home processor"; Store, desc="Store request from the home processor"; @@ -94,17 +106,17 @@ machine(MachineType:L0Cache, "MESI Directory L0 Cache") // internal generated request L0_Replacement, desc="L0 Replacement", format="!r"; - // other requests + // requests forwarded from other processors Fwd_GETX, desc="GETX from other processor"; Fwd_GETS, desc="GETS from other processor"; Fwd_GET_INSTR, desc="GET_INSTR from other processor"; + // data arrives from L1 cache Data, desc="Data for processor"; Data_Exclusive, desc="Data for processor"; Data_Stale, desc="Data for processor, but not for storage"; Ack, desc="Ack for processor"; - Ack_all, desc="Last ack for processor"; WB_Ack, desc="Ack for replacement"; } @@ -419,7 +431,7 @@ machine(MachineType:L0Cache, "MESI Directory L0 Cache") } } - action(f_sendDataToL1, "f", desc="send data to the L2 cache") { + action(f_sendDataToL1, "f", desc="Send data to the L1 cache") { enqueue(requestNetwork_out, CoherenceMsg, response_latency) { assert(is_valid(cache_entry)); out_msg.addr := address; @@ -433,7 +445,7 @@ machine(MachineType:L0Cache, "MESI Directory L0 Cache") cache_entry.Dirty := false; } - action(fi_sendInvAck, "fi", desc="send data to the L2 cache") { + action(fi_sendInvAck, "fi", desc="Send data to the L1 cache") { peek(messgeBuffer_in, CoherenceMsg) { enqueue(requestNetwork_out, CoherenceMsg, response_latency) { out_msg.addr := address; @@ -445,14 +457,14 @@ machine(MachineType:L0Cache, "MESI Directory L0 Cache") } } - action(forward_eviction_to_cpu, "\cc", desc="sends eviction information to the processor") { + action(forward_eviction_to_cpu, "\cc", desc="Send eviction information to the processor") { if (send_evictions) { DPRINTF(RubySlicc, "Sending invalidation for %#x to the CPU\n", address); sequencer.evictionCallback(address); } } - action(g_issuePUTX, "g", desc="send data to the L2 cache") { + action(g_issuePUTX, "g", desc="Relinquish line to the L1 cache") { enqueue(requestNetwork_out, CoherenceMsg, response_latency) { assert(is_valid(cache_entry)); out_msg.addr := address; @@ -470,35 +482,41 @@ machine(MachineType:L0Cache, "MESI Directory L0 Cache") } } - action(h_load_hit, "hd", desc="If not prefetch, notify sequencer the load completed.") { + action(h_load_hit, "hd", desc="Notify sequencer the load completed (cache hit)") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); Dcache.setMRU(cache_entry); sequencer.readCallback(address, cache_entry.DataBlk); } - action(h_ifetch_hit, "hi", desc="If not prefetch, notify sequencer the ifetch completed.") { + action(h_ifetch_hit, "hi", desc="Notify sequencer the ifetch completed (cache hit)") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); Icache.setMRU(cache_entry); sequencer.readCallback(address, cache_entry.DataBlk); } - action(hx_load_hit, "hxd", desc="notify sequencer the load completed.") { + // The action name uses a counterintuitive _hit prefix when it is only + // called due to a cache miss. It is technically now a hit after having + // serviced the miss. + action(hx_load_hit, "hxd", desc="Notify sequencer the load completed (cache miss)") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); Dcache.setMRU(cache_entry); sequencer.readCallback(address, cache_entry.DataBlk, true); } - action(hx_ifetch_hit, "hxi", desc="notify sequencer the ifetch completed.") { + // The action name uses a counterintuitive _hit prefix when it is only + // called due to a cache miss. It is technically now a hit after having + // serviced the miss. + action(hx_ifetch_hit, "hxi", desc="Notify sequencer the ifetch completed (cache miss)") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); Icache.setMRU(cache_entry); sequencer.readCallback(address, cache_entry.DataBlk, true); } - action(hh_store_hit, "\h", desc="If not prefetch, notify sequencer that store completed.") { + action(hh_store_hit, "\h", desc="Notify sequencer that store completed (cache hit)") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); Dcache.setMRU(cache_entry); @@ -506,7 +524,10 @@ machine(MachineType:L0Cache, "MESI Directory L0 Cache") cache_entry.Dirty := true; } - action(hhx_store_hit, "\hx", desc="If not prefetch, notify sequencer that store completed.") { + // The action name uses a counterintuitive _hit prefix when it is only + // called due to a cache miss. It is technically now a hit after having + // serviced the miss. + action(hhx_store_hit, "\hx", desc="Notify sequencer that store completed (cache miss)") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); Dcache.setMRU(cache_entry); @@ -523,7 +544,7 @@ machine(MachineType:L0Cache, "MESI Directory L0 Cache") tbe.DataBlk := cache_entry.DataBlk; } - action(k_popMandatoryQueue, "k", desc="Pop mandatory queue.") { + action(k_popMandatoryQueue, "k", desc="Pop mandatory queue") { mandatoryQueue_in.dequeue(clockEdge()); } @@ -568,23 +589,23 @@ machine(MachineType:L0Cache, "MESI Directory L0 Cache") unset_cache_entry(); } - action(oo_allocateDCacheBlock, "\o", desc="Set L1 D-cache tag equal to tag of block B.") { + action(oo_allocateDCacheBlock, "\o", desc="Set L1 D-cache tag equal to tag of block B") { if (is_invalid(cache_entry)) { set_cache_entry(Dcache.allocate(address, new Entry)); } } - action(pp_allocateICacheBlock, "\p", desc="Set L1 I-cache tag equal to tag of block B.") { + action(pp_allocateICacheBlock, "\p", desc="Set L1 I-cache tag equal to tag of block B") { if (is_invalid(cache_entry)) { set_cache_entry(Icache.allocate(address, new Entry)); } } - action(z_stallAndWaitMandatoryQueue, "\z", desc="recycle cpu request queue") { + action(z_stallAndWaitMandatoryQueue, "\z", desc="Stall cpu request queue") { stall_and_wait(mandatoryQueue_in, address); } - action(kd_wakeUpDependents, "kd", desc="wake-up dependents") { + action(kd_wakeUpDependents, "kd", desc="Wake-up dependents") { wakeUpAllBuffers(address); } @@ -592,7 +613,7 @@ machine(MachineType:L0Cache, "MESI Directory L0 Cache") ++Icache.demand_misses; } - action(uu_profileInstHit, "\uih", desc="Profile the demand miss") { + action(uu_profileInstHit, "\uih", desc="Profile the demand hit") { ++Icache.demand_hits; } @@ -600,7 +621,7 @@ machine(MachineType:L0Cache, "MESI Directory L0 Cache") ++Dcache.demand_misses; } - action(uu_profileDataHit, "\udh", desc="Profile the demand miss") { + action(uu_profileDataHit, "\udh", desc="Profile the demand hit") { ++Dcache.demand_hits; } diff --git a/src/mem/ruby/protocol/MESI_Three_Level-L1cache.sm b/src/mem/ruby/protocol/MESI_Three_Level-L1cache.sm index 79d554d39..0edeed8fd 100644 --- a/src/mem/ruby/protocol/MESI_Three_Level-L1cache.sm +++ b/src/mem/ruby/protocol/MESI_Three_Level-L1cache.sm @@ -1,4 +1,16 @@ /* + * Copyright (c) 2020 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 1999-2013 Mark D. Hill and David A. Wood * All rights reserved. * @@ -59,13 +71,13 @@ machine(MachineType:L1Cache, "MESI Directory L1 Cache CMP") // STATES state_declaration(State, desc="Cache states", default="L1Cache_State_I") { // Base states - I, AccessPermission:Invalid, desc="a L1 cache entry Idle"; - S, AccessPermission:Read_Only, desc="a L1 cache entry Shared"; - SS, AccessPermission:Read_Only, desc="a L1 cache entry Shared"; - E, AccessPermission:Read_Only, desc="a L1 cache entry Exclusive"; - EE, AccessPermission:Read_Write, desc="a L1 cache entry Exclusive"; - M, AccessPermission:Maybe_Stale, desc="a L1 cache entry Modified", format="!b"; - MM, AccessPermission:Read_Write, desc="a L1 cache entry Modified", format="!b"; + I, AccessPermission:Invalid, desc="L1 cache entry Idle"; + S, AccessPermission:Read_Only, desc="Line is present in shared state in L1 and L0"; + SS, AccessPermission:Read_Only, desc="Line is present in shared state in L1 but not L0"; + E, AccessPermission:Read_Only, desc="Line is present in exclusive state in L1 and L0"; + EE, AccessPermission:Read_Write, desc="Line is present in exclusive state in L1 but not L0"; + M, AccessPermission:Maybe_Stale, desc="Line is present in modified state in L1 and present in L0", format="!b"; + MM, AccessPermission:Read_Write, desc="Line is present in modified state in L1 but not present in L0", format="!b"; // Transient States IS, AccessPermission:Busy, desc="L1 idle, issued GETS, have not seen response yet"; @@ -78,11 +90,11 @@ machine(MachineType:L1Cache, "MESI Directory L1 Cache CMP") // For all of the following states, invalidate // message has been sent to L0 cache. The response // from the L0 cache has not been seen yet. - S_IL0, AccessPermission:Busy; - E_IL0, AccessPermission:Busy; - M_IL0, AccessPermission:Busy; - MM_IL0, AccessPermission:Read_Write; - SM_IL0, AccessPermission:Busy; + S_IL0, AccessPermission:Busy, desc="Shared in L1, invalidation sent to L0, have not seen response yet"; + E_IL0, AccessPermission:Busy, desc="Exclusive in L1, invalidation sent to L0, have not seen response yet"; + M_IL0, AccessPermission:Busy, desc="Modified in L1, invalidation sent to L0, have not seen response yet"; + MM_IL0, AccessPermission:Read_Write, desc="Invalidation sent to L0, have not seen response yet"; + SM_IL0, AccessPermission:Busy, desc="Invalidation sent to L0, have not seen response yet"; } // EVENTS @@ -95,17 +107,14 @@ machine(MachineType:L1Cache, "MESI Directory L1 Cache CMP") // Responses from the L0 Cache // L0 cache received the invalidation message // and has sent the data. - L0_DataAck; + L0_DataAck, desc="L0 received INV message"; Inv, desc="Invalidate request from L2 bank"; - // internal generated request - // Invalidate the line in L0 due to own requirements - L0_Invalidate_Own; - // Invalidate the line in L0 due to some other cache's requirements - L0_Invalidate_Else; - // Invalidate the line in the cache due to some one else / space needs. - L1_Replacement; + // internally generated requests: + L0_Invalidate_Own, desc="Invalidate line in L0, due to this cache's (L1) requirements"; + L0_Invalidate_Else, desc="Invalidate line in L0, due to another cache's requirements"; + L1_Replacement, desc="Invalidate line in this cache (L1), due to another cache's requirements"; // other requests Fwd_GETX, desc="GETX from other processor"; -- 2.30.2