summaryrefslogtreecommitdiff
path: root/src/mem
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem')
-rw-r--r--src/mem/protocol/MESI_CMP_directory-L1cache.sm37
-rw-r--r--src/mem/protocol/MESI_CMP_directory-L2cache.sm49
-rw-r--r--src/mem/protocol/MESI_CMP_directory-dir.sm24
-rw-r--r--src/mem/protocol/MESI_CMP_directory-dma.sm8
-rw-r--r--src/mem/protocol/MI_example-cache.sm21
-rw-r--r--src/mem/protocol/MI_example-dir.sm22
-rw-r--r--src/mem/protocol/MI_example-dma.sm8
-rw-r--r--src/mem/protocol/MOESI_CMP_directory-L1cache.sm46
-rw-r--r--src/mem/protocol/MOESI_CMP_directory-L2cache.sm133
-rw-r--r--src/mem/protocol/MOESI_CMP_directory-dir.sm42
-rw-r--r--src/mem/protocol/MOESI_CMP_directory-dma.sm8
-rw-r--r--src/mem/protocol/MOESI_CMP_token-L1cache.sm53
-rw-r--r--src/mem/protocol/MOESI_CMP_token-L2cache.sm27
-rw-r--r--src/mem/protocol/MOESI_CMP_token-dir.sm34
-rw-r--r--src/mem/protocol/MOESI_CMP_token-dma.sm8
-rw-r--r--src/mem/protocol/MOESI_hammer-cache.sm61
-rw-r--r--src/mem/protocol/MOESI_hammer-dir.sm60
-rw-r--r--src/mem/protocol/MOESI_hammer-dma.sm10
-rw-r--r--src/mem/protocol/RubySlicc_Types.sm4
-rw-r--r--src/mem/ruby/slicc_interface/AbstractCacheEntry.cc10
-rw-r--r--src/mem/ruby/slicc_interface/AbstractCacheEntry.hh5
-rw-r--r--src/mem/ruby/slicc_interface/AbstractEntry.cc13
-rw-r--r--src/mem/ruby/slicc_interface/AbstractEntry.hh7
-rw-r--r--src/mem/slicc/ast/StateDeclAST.py79
-rw-r--r--src/mem/slicc/ast/TypeFieldEnumAST.py9
-rw-r--r--src/mem/slicc/ast/TypeFieldStateAST.py61
-rw-r--r--src/mem/slicc/ast/__init__.py2
-rw-r--r--src/mem/slicc/parser.py20
-rw-r--r--src/mem/slicc/symbols/StateMachine.py13
-rw-r--r--src/mem/slicc/symbols/Type.py40
30 files changed, 524 insertions, 390 deletions
diff --git a/src/mem/protocol/MESI_CMP_directory-L1cache.sm b/src/mem/protocol/MESI_CMP_directory-L1cache.sm
index 4442cee41..ecd8c9681 100644
--- a/src/mem/protocol/MESI_CMP_directory-L1cache.sm
+++ b/src/mem/protocol/MESI_CMP_directory-L1cache.sm
@@ -52,23 +52,23 @@ machine(L1Cache, "MSI Directory L1 Cache CMP")
MessageBuffer responseToL1Cache, network="From", virtual_network="1", ordered="false";
// STATES
- enumeration(State, desc="Cache states", default="L1Cache_State_I") {
+ state_declaration(State, desc="Cache states", default="L1Cache_State_I") {
// Base states
- NP, desc="Not present in either cache";
- I, desc="a L1 cache entry Idle";
- S, desc="a L1 cache entry Shared";
- E, desc="a L1 cache entry Exclusive";
- M, desc="a L1 cache entry Modified", format="!b";
+ NP, AccessPermission:Invalid, desc="Not present in either cache";
+ I, AccessPermission:Invalid, desc="a L1 cache entry Idle";
+ S, AccessPermission:Read_Only, desc="a L1 cache entry Shared";
+ E, AccessPermission:Read_Only, desc="a L1 cache entry Exclusive";
+ M, AccessPermission:Read_Write, desc="a L1 cache entry Modified", format="!b";
// Transient States
- IS, desc="L1 idle, issued GETS, have not seen response yet";
- IM, desc="L1 idle, issued GETX, have not seen response yet";
- SM, desc="L1 idle, issued GETX, have not seen response yet";
- IS_I, desc="L1 idle, issued GETS, saw Inv before data because directory doesn't block on GETS hit";
+ IS, AccessPermission:Busy, desc="L1 idle, issued GETS, have not seen response yet";
+ IM, AccessPermission:Busy, desc="L1 idle, issued GETX, have not seen response yet";
+ SM, AccessPermission:Read_Only, desc="L1 idle, issued GETX, have not seen response yet";
+ IS_I, AccessPermission:Busy, desc="L1 idle, issued GETS, saw Inv before data because directory doesn't block on GETS hit";
- M_I, desc="L1 replacing, waiting for ACK";
- E_I, desc="L1 replacing, waiting for ACK";
- SINK_WB_ACK, desc="This is to sink WB_Acks from L2";
+ M_I, AccessPermission:Busy, desc="L1 replacing, waiting for ACK";
+ E_I, AccessPermission:Busy, desc="L1 replacing, waiting for ACK";
+ SINK_WB_ACK, AccessPermission:Busy, desc="This is to sink WB_Acks from L2";
}
@@ -180,17 +180,6 @@ machine(L1Cache, "MSI Directory L1 Cache CMP")
if (is_valid(cache_entry)) {
cache_entry.CacheState := state;
-
- // Set permission
- if (state == State:I) {
- cache_entry.changePermission(AccessPermission:Invalid);
- } else if (state == State:S || state == State:E) {
- cache_entry.changePermission(AccessPermission:Read_Only);
- } else if (state == State:M) {
- cache_entry.changePermission(AccessPermission:Read_Write);
- } else {
- cache_entry.changePermission(AccessPermission:Busy);
- }
}
}
diff --git a/src/mem/protocol/MESI_CMP_directory-L2cache.sm b/src/mem/protocol/MESI_CMP_directory-L2cache.sm
index aeaf3d60d..c30e42e69 100644
--- a/src/mem/protocol/MESI_CMP_directory-L2cache.sm
+++ b/src/mem/protocol/MESI_CMP_directory-L2cache.sm
@@ -51,33 +51,33 @@ machine(L2Cache, "MESI Directory L2 Cache CMP")
// MessageBuffer unblockToL2Cache, network="From", virtual_network="4", ordered="false"; // a local L1 || Memory -> this L2 bank
// STATES
- enumeration(State, desc="L2 Cache states", default="L2Cache_State_NP") {
+ state_declaration(State, desc="L2 Cache states", default="L2Cache_State_NP") {
// Base states
- NP, desc="Not present in either cache";
- SS, desc="L2 cache entry Shared, also present in one or more L1s";
- M, desc="L2 cache entry Modified, not present in any L1s", format="!b";
- MT, desc="L2 cache entry Modified in a local L1, assume L2 copy stale", format="!b";
+ NP, AccessPermission:Invalid, desc="Not present in either cache";
+ SS, AccessPermission:Read_Only, desc="L2 cache entry Shared, also present in one or more L1s";
+ M, AccessPermission:Read_Write, desc="L2 cache entry Modified, not present in any L1s", format="!b";
+ MT, AccessPermission:Invalid, desc="L2 cache entry Modified in a local L1, assume L2 copy stale", format="!b";
// L2 replacement
- M_I, desc="L2 cache replacing, have all acks, sent dirty data to memory, waiting for ACK from memory";
- MT_I, desc="L2 cache replacing, getting data from exclusive";
- MCT_I, desc="L2 cache replacing, clean in L2, getting data or ack from exclusive";
- I_I, desc="L2 replacing clean data, need to inv sharers and then drop data";
- S_I, desc="L2 replacing dirty data, collecting acks from L1s";
+ M_I, AccessPermission:Busy, desc="L2 cache replacing, have all acks, sent dirty data to memory, waiting for ACK from memory";
+ MT_I, AccessPermission:Busy, desc="L2 cache replacing, getting data from exclusive";
+ MCT_I, AccessPermission:Busy, desc="L2 cache replacing, clean in L2, getting data or ack from exclusive";
+ I_I, AccessPermission:Busy, desc="L2 replacing clean data, need to inv sharers and then drop data";
+ S_I, AccessPermission:Busy, desc="L2 replacing dirty data, collecting acks from L1s";
// Transient States for fetching data from memory
- ISS, desc="L2 idle, got single L1_GETS, issued memory fetch, have not seen response yet";
- IS, desc="L2 idle, got L1_GET_INSTR or multiple L1_GETS, issued memory fetch, have not seen response yet";
- IM, desc="L2 idle, got L1_GETX, issued memory fetch, have not seen response(s) yet";
+ ISS, AccessPermission:Busy, desc="L2 idle, got single L1_GETS, issued memory fetch, have not seen response yet";
+ IS, AccessPermission:Busy, desc="L2 idle, got L1_GET_INSTR or multiple L1_GETS, issued memory fetch, have not seen response yet";
+ IM, AccessPermission:Busy, desc="L2 idle, got L1_GETX, issued memory fetch, have not seen response(s) yet";
// Blocking states
- SS_MB, desc="Blocked for L1_GETX from SS";
- MT_MB, desc="Blocked for L1_GETX from MT";
- M_MB, desc="Blocked for L1_GETX from M";
+ SS_MB, AccessPermission:Busy, desc="Blocked for L1_GETX from SS";
+ MT_MB, AccessPermission:Busy, desc="Blocked for L1_GETX from MT";
+ M_MB, AccessPermission:Busy, desc="Blocked for L1_GETX from M";
- MT_IIB, desc="Blocked for L1_GETS from MT, waiting for unblock and data";
- MT_IB, desc="Blocked for L1_GETS from MT, got unblock, waiting for data";
- MT_SB, desc="Blocked for L1_GETS from MT, got data, waiting for unblock";
+ MT_IIB, AccessPermission:Busy, desc="Blocked for L1_GETS from MT, waiting for unblock and data";
+ MT_IB, AccessPermission:Busy, desc="Blocked for L1_GETS from MT, got unblock, waiting for data";
+ MT_SB, AccessPermission:Busy, desc="Blocked for L1_GETS from MT, got data, waiting for unblock";
}
@@ -212,17 +212,6 @@ machine(L2Cache, "MESI Directory L2 Cache CMP")
if (is_valid(cache_entry)) {
cache_entry.CacheState := state;
-
- // Set permission
- if (state == State:SS ) {
- cache_entry.changePermission(AccessPermission:Read_Only);
- } else if (state == State:M) {
- cache_entry.changePermission(AccessPermission:Read_Write);
- } else if (state == State:MT) {
- cache_entry.changePermission(AccessPermission:Invalid);
- } else {
- cache_entry.changePermission(AccessPermission:Busy);
- }
}
}
diff --git a/src/mem/protocol/MESI_CMP_directory-dir.sm b/src/mem/protocol/MESI_CMP_directory-dir.sm
index 0c3532fbf..46c14bc0f 100644
--- a/src/mem/protocol/MESI_CMP_directory-dir.sm
+++ b/src/mem/protocol/MESI_CMP_directory-dir.sm
@@ -49,19 +49,19 @@ machine(Directory, "MESI_CMP_filter_directory protocol")
MessageBuffer responseFromDir, network="To", virtual_network="1", ordered="false";
// STATES
- enumeration(State, desc="Directory states", default="Directory_State_I") {
+ state_declaration(State, desc="Directory states", default="Directory_State_I") {
// Base states
- I, desc="Owner";
- ID, desc="Intermediate state for DMA_READ when in I";
- ID_W, desc="Intermediate state for DMA_WRITE when in I";
-
- M, desc="Modified";
- IM, desc="Intermediate State I>M";
- MI, desc="Intermediate State M>I";
- M_DRD, desc="Intermediate State when there is a dma read";
- M_DRDI, desc="Intermediate State when there is a dma read";
- M_DWR, desc="Intermediate State when there is a dma write";
- M_DWRI, desc="Intermediate State when there is a dma write";
+ I, AccessPermission:Read_Write, desc="dir is the owner and memory is up-to-date, all other copies are Invalid";
+ ID, AccessPermission:Busy, desc="Intermediate state for DMA_READ when in I";
+ ID_W, AccessPermission:Busy, desc="Intermediate state for DMA_WRITE when in I";
+
+ M, AccessPermission:Invalid, desc="memory copy may be stale, i.e. other modified copies may exist";
+ IM, AccessPermission:Busy, desc="Intermediate State I>M";
+ MI, AccessPermission:Busy, desc="Intermediate State M>I";
+ M_DRD, AccessPermission:Busy, desc="Intermediate State when there is a dma read";
+ M_DRDI, AccessPermission:Busy, desc="Intermediate State when there is a dma read";
+ M_DWR, AccessPermission:Busy, desc="Intermediate State when there is a dma write";
+ M_DWRI, AccessPermission:Busy, desc="Intermediate State when there is a dma write";
}
// Events
diff --git a/src/mem/protocol/MESI_CMP_directory-dma.sm b/src/mem/protocol/MESI_CMP_directory-dma.sm
index fe1cd2fb4..3fab439c6 100644
--- a/src/mem/protocol/MESI_CMP_directory-dma.sm
+++ b/src/mem/protocol/MESI_CMP_directory-dma.sm
@@ -7,10 +7,10 @@ machine(DMA, "DMA Controller")
MessageBuffer responseFromDir, network="From", virtual_network="1", ordered="true", no_vector="true";
MessageBuffer reqToDirectory, network="To", virtual_network="0", ordered="false", no_vector="true";
- enumeration(State, desc="DMA states", default="DMA_State_READY") {
- READY, desc="Ready to accept a new request";
- BUSY_RD, desc="Busy: currently processing a request";
- BUSY_WR, desc="Busy: currently processing a request";
+ state_declaration(State, desc="DMA states", default="DMA_State_READY") {
+ READY, AccessPermission:Invalid, desc="Ready to accept a new request";
+ BUSY_RD, AccessPermission:Busy, desc="Busy: currently processing a request";
+ BUSY_WR, AccessPermission:Busy, desc="Busy: currently processing a request";
}
enumeration(Event, desc="DMA events") {
diff --git a/src/mem/protocol/MI_example-cache.sm b/src/mem/protocol/MI_example-cache.sm
index 96b7ab826..26572770c 100644
--- a/src/mem/protocol/MI_example-cache.sm
+++ b/src/mem/protocol/MI_example-cache.sm
@@ -14,15 +14,15 @@ machine(L1Cache, "MI Example L1 Cache")
MessageBuffer responseToCache, network="From", virtual_network="4", ordered="true";
// STATES
- enumeration(State, desc="Cache states") {
- I, desc="Not Present/Invalid";
- II, desc="Not Present/Invalid, issued PUT";
- M, desc="Modified";
- MI, desc="Modified, issued PUT";
- MII, desc="Modified, issued PUTX, received nack";
+ state_declaration(State, desc="Cache states") {
+ I, AccessPermission:Invalid, desc="Not Present/Invalid";
+ II, AccessPermission:Busy, desc="Not Present/Invalid, issued PUT";
+ M, AccessPermission:Read_Write, desc="Modified";
+ MI, AccessPermission:Busy, desc="Modified, issued PUT";
+ MII, AccessPermission:Busy, desc="Modified, issued PUTX, received nack";
- IS, desc="Issued request for LOAD/IFETCH";
- IM, desc="Issued request for STORE/ATOMIC";
+ IS, AccessPermission:Busy, desc="Issued request for LOAD/IFETCH";
+ IM, AccessPermission:Busy, desc="Issued request for STORE/ATOMIC";
}
// EVENTS
@@ -117,11 +117,6 @@ machine(L1Cache, "MI Example L1 Cache")
if (is_valid(cache_entry)) {
cache_entry.CacheState := state;
- if (state == State:M) {
- cache_entry.changePermission(AccessPermission:Read_Write);
- } else {
- cache_entry.changePermission(AccessPermission:Invalid);
- }
}
}
diff --git a/src/mem/protocol/MI_example-dir.sm b/src/mem/protocol/MI_example-dir.sm
index 30720e433..d4ba3829d 100644
--- a/src/mem/protocol/MI_example-dir.sm
+++ b/src/mem/protocol/MI_example-dir.sm
@@ -13,21 +13,21 @@ machine(Directory, "Directory protocol")
MessageBuffer dmaRequestToDir, network="From", virtual_network="0", ordered="true";
// STATES
- enumeration(State, desc="Directory states", default="Directory_State_I") {
+ state_declaration(State, desc="Directory states", default="Directory_State_I") {
// Base states
- I, desc="Invalid";
- M, desc="Modified";
+ I, AccessPermission:Read_Write, desc="Invalid";
+ M, AccessPermission:Invalid, desc="Modified";
- M_DRD, desc="Blocked on an invalidation for a DMA read";
- M_DWR, desc="Blocked on an invalidation for a DMA write";
+ M_DRD, AccessPermission:Busy, desc="Blocked on an invalidation for a DMA read";
+ M_DWR, AccessPermission:Busy, desc="Blocked on an invalidation for a DMA write";
- M_DWRI, desc="Intermediate state M_DWR-->I";
- M_DRDI, desc="Intermediate state M_DRD-->I";
+ M_DWRI, AccessPermission:Busy, desc="Intermediate state M_DWR-->I";
+ M_DRDI, AccessPermission:Busy, desc="Intermediate state M_DRD-->I";
- IM, desc="Intermediate state I-->M";
- MI, desc="Intermediate state M-->I";
- ID, desc="Intermediate state for DMA_READ when in I";
- ID_W, desc="Intermediate state for DMA_WRITE when in I";
+ IM, AccessPermission:Busy, desc="Intermediate state I-->M";
+ MI, AccessPermission:Busy, desc="Intermediate state M-->I";
+ ID, AccessPermission:Busy, desc="Intermediate state for DMA_READ when in I";
+ ID_W, AccessPermission:Busy, desc="Intermediate state for DMA_WRITE when in I";
}
// Events
diff --git a/src/mem/protocol/MI_example-dma.sm b/src/mem/protocol/MI_example-dma.sm
index 3e52ae5f6..878af538e 100644
--- a/src/mem/protocol/MI_example-dma.sm
+++ b/src/mem/protocol/MI_example-dma.sm
@@ -7,10 +7,10 @@ machine(DMA, "DMA Controller")
MessageBuffer responseFromDir, network="From", virtual_network="1", ordered="true", no_vector="true";
MessageBuffer reqToDirectory, network="To", virtual_network="0", ordered="false", no_vector="true";
- enumeration(State, desc="DMA states", default="DMA_State_READY") {
- READY, desc="Ready to accept a new request";
- BUSY_RD, desc="Busy: currently processing a request";
- BUSY_WR, desc="Busy: currently processing a request";
+ state_declaration(State, desc="DMA states", default="DMA_State_READY") {
+ READY, AccessPermission:Invalid, desc="Ready to accept a new request";
+ BUSY_RD, AccessPermission:Busy, desc="Busy: currently processing a request";
+ BUSY_WR, AccessPermission:Busy, desc="Busy: currently processing a request";
}
enumeration(Event, desc="DMA events") {
diff --git a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm
index e590c952a..50df2e52a 100644
--- a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm
+++ b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm
@@ -58,25 +58,25 @@ machine(L1Cache, "Directory protocol")
// STATES
- enumeration(State, desc="Cache states", default="L1Cache_State_I") {
+ state_declaration(State, desc="Cache states", default="L1Cache_State_I") {
// Base states
- I, desc="Idle";
- S, desc="Shared";
- O, desc="Owned";
- M, desc="Modified (dirty)";
- M_W, desc="Modified (dirty)";
- MM, desc="Modified (dirty and locally modified)";
- MM_W, desc="Modified (dirty and locally modified)";
+ I, AccessPermission:Invalid, desc="Idle";
+ S, AccessPermission:Read_Only, desc="Shared";
+ O, AccessPermission:Read_Only, desc="Owned";
+ M, AccessPermission:Read_Only, desc="Modified (dirty)";
+ M_W, AccessPermission:Read_Only, desc="Modified (dirty)";
+ MM, AccessPermission:Read_Write, desc="Modified (dirty and locally modified)";
+ MM_W, AccessPermission:Read_Write, desc="Modified (dirty and locally modified)";
// Transient States
- IM, "IM", desc="Issued GetX";
- SM, "SM", desc="Issued GetX, we still have an old copy of the line";
- OM, "SM", desc="Issued GetX, received data";
- IS, "IS", desc="Issued GetS";
- SI, "OI", desc="Issued PutS, waiting for ack";
- OI, "OI", desc="Issued PutO, waiting for ack";
- MI, "MI", desc="Issued PutX, waiting for ack";
- II, "II", desc="Issued PutX/O, saw Fwd_GETS or Fwd_GETX, waiting for ack";
+ IM, AccessPermission:Busy, "IM", desc="Issued GetX";
+ SM, AccessPermission:Read_Only, "SM", desc="Issued GetX, we still have an old copy of the line";
+ OM, AccessPermission:Read_Only, "SM", desc="Issued GetX, received data";
+ IS, AccessPermission:Busy, "IS", desc="Issued GetS";
+ SI, AccessPermission:Busy, "OI", desc="Issued PutS, waiting for ack";
+ 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 Fwd_GETS or Fwd_GETX, waiting for ack";
}
// EVENTS
@@ -191,20 +191,6 @@ machine(L1Cache, "Directory protocol")
else {
cache_entry.CacheState := state;
}
-
- // Set permission
- if (state == State:MM || state == State:MM_W) {
- cache_entry.changePermission(AccessPermission:Read_Write);
- } else if ((state == State:S) ||
- (state == State:O) ||
- (state == State:M) ||
- (state == State:M_W) ||
- (state == State:SM) ||
- (state == State:OM)) {
- cache_entry.changePermission(AccessPermission:Read_Only);
- } else {
- cache_entry.changePermission(AccessPermission:Invalid);
- }
}
}
diff --git a/src/mem/protocol/MOESI_CMP_directory-L2cache.sm b/src/mem/protocol/MOESI_CMP_directory-L2cache.sm
index a638b171f..cdc91c292 100644
--- a/src/mem/protocol/MOESI_CMP_directory-L2cache.sm
+++ b/src/mem/protocol/MOESI_CMP_directory-L2cache.sm
@@ -51,80 +51,80 @@ machine(L2Cache, "Token protocol")
// MessageBuffer L1WritebackToL2Cache, network="From", virtual_network="3", ordered="false";
// STATES
- enumeration(State, desc="L2 Cache states", default="L2Cache_State_I") {
+ state_declaration(State, desc="L2 Cache states", default="L2Cache_State_I") {
// Stable states
- NP, desc="Not Present";
- I, desc="Invalid";
- ILS, desc="Idle/NP, but local sharers exist";
- ILX, desc="Idle/NP, but local exclusive exists";
- ILO, desc="Idle/NP, but local owner exists";
- ILOX, desc="Idle/NP, but local owner exists and chip is exclusive";
- ILOS, desc="Idle/NP, but local owner exists and local sharers as well";
- ILOSX, desc="Idle/NP, but local owner exists, local sharers exist, chip is exclusive ";
- S, desc="Shared, no local sharers";
- O, desc="Owned, no local sharers";
- OLS, desc="Owned with local sharers";
- OLSX, desc="Owned with local sharers, chip is exclusive";
- SLS, desc="Shared with local sharers";
- M, desc="Modified";
+ NP, AccessPermission:Invalid, desc="Not Present";
+ I, AccessPermission:Invalid, desc="Invalid";
+ ILS, AccessPermission:Busy, desc="Idle/NP, but local sharers exist";
+ ILX, AccessPermission:Busy, desc="Idle/NP, but local exclusive exists";
+ ILO, AccessPermission:Busy, desc="Idle/NP, but local owner exists";
+ ILOX, AccessPermission:Busy, desc="Idle/NP, but local owner exists and chip is exclusive";
+ ILOS, AccessPermission:Busy, desc="Idle/NP, but local owner exists and local sharers as well";
+ ILOSX, AccessPermission:Busy, desc="Idle/NP, but local owner exists, local sharers exist, chip is exclusive ";
+ S, AccessPermission:Read_Only, desc="Shared, no local sharers";
+ O, AccessPermission:Read_Only, desc="Owned, no local sharers";
+ OLS, AccessPermission:Read_Only, desc="Owned with local sharers";
+ OLSX, AccessPermission:Read_Only, desc="Owned with local sharers, chip is exclusive";
+ SLS, AccessPermission:Read_Only, desc="Shared with local sharers";
+ M, AccessPermission:Read_Write, desc="Modified";
// Transient States
- IFGX, desc="Blocked, forwarded global GETX to local owner/exclusive. No other on-chip invs needed";
- IFGS, desc="Blocked, forwarded global GETS to local owner";
- ISFGS, desc="Blocked, forwarded global GETS to local owner, local sharers exist";
+ IFGX, AccessPermission:Busy, desc="Blocked, forwarded global GETX to local owner/exclusive. No other on-chip invs needed";
+ IFGS, AccessPermission:Busy, desc="Blocked, forwarded global GETS to local owner";
+ ISFGS, AccessPermission:Busy, desc="Blocked, forwarded global GETS to local owner, local sharers exist";
// UNUSED
- IFGXX, desc="Blocked, forwarded global GETX to local owner but may need acks from other sharers";
- OFGX, desc="Blocked, forwarded global GETX to owner and got data but may need acks";
+ IFGXX, AccessPermission:Busy, desc="Blocked, forwarded global GETX to local owner but may need acks from other sharers";
+ OFGX, AccessPermission:Busy, desc="Blocked, forwarded global GETX to owner and got data but may need acks";
- OLSF, desc="Blocked, got Fwd_GETX with local sharers, waiting for local inv acks";
+ OLSF, AccessPermission:Busy, desc="Blocked, got Fwd_GETX with local sharers, waiting for local inv acks";
// writebacks
- ILOW, desc="local WB request, was ILO";
- ILOXW, desc="local WB request, was ILOX";
- ILOSW, desc="local WB request, was ILOS";
- ILOSXW, desc="local WB request, was ILOSX";
- SLSW, desc="local WB request, was SLS";
- OLSW, desc="local WB request, was OLS";
- ILSW, desc="local WB request, was ILS";
- IW, desc="local WB request from only sharer, was ILS";
- OW, desc="local WB request from only sharer, was OLS";
- SW, desc="local WB request from only sharer, was SLS";
- OXW, desc="local WB request from only sharer, was OLSX";
- OLSXW, desc="local WB request from sharer, was OLSX";
- ILXW, desc="local WB request, was ILX";
-
- IFLS, desc="Blocked, forwarded local GETS to _some_ local sharer";
- IFLO, desc="Blocked, forwarded local GETS to local owner";
- IFLOX, desc="Blocked, forwarded local GETS to local owner but chip is exclusive";
- IFLOXX, desc="Blocked, forwarded local GETX to local owner/exclusive, chip is exclusive";
- IFLOSX, desc="Blocked, forwarded local GETS to local owner w/ other sharers, chip is exclusive";
- IFLXO, desc="Blocked, forwarded local GETX to local owner with other sharers, chip is exclusive";
-
- IGS, desc="Semi-blocked, issued local GETS to directory";
- IGM, desc="Blocked, issued local GETX to directory. Need global acks and data";
- IGMLS, desc="Blocked, issued local GETX to directory but may need to INV local sharers";
- IGMO, desc="Blocked, have data for local GETX but need all acks";
- IGMIO, desc="Blocked, issued local GETX, local owner with possible local sharer, may need to INV";
- OGMIO, desc="Blocked, issued local GETX, was owner, may need to INV";
- IGMIOF, desc="Blocked, issued local GETX, local owner, waiting for global acks, got Fwd_GETX";
- IGMIOFS, desc="Blocked, issued local GETX, local owner, waiting for global acks, got Fwd_GETS";
- OGMIOF, desc="Blocked, issued local GETX, was owner, waiting for global acks, got Fwd_GETX";
-
- II, desc="Blocked, handling invalidations";
- MM, desc="Blocked, was M satisfying local GETX";
- SS, desc="Blocked, was S satisfying local GETS";
- OO, desc="Blocked, was O satisfying local GETS";
- OLSS, desc="Blocked, satisfying local GETS";
- OLSXS, desc="Blocked, satisfying local GETS";
- SLSS, desc="Blocked, satisfying local GETS";
-
- OI, desc="Blocked, doing writeback, was O";
- MI, desc="Blocked, doing writeback, was M";
- MII, desc="Blocked, doing writeback, was M, got Fwd_GETX";
- OLSI, desc="Blocked, doing writeback, was OLS";
- ILSI, desc="Blocked, doing writeback, was OLS got Fwd_GETX";
+ ILOW, AccessPermission:Busy, desc="local WB request, was ILO";
+ ILOXW, AccessPermission:Busy, desc="local WB request, was ILOX";
+ ILOSW, AccessPermission:Busy, desc="local WB request, was ILOS";
+ ILOSXW, AccessPermission:Busy, desc="local WB request, was ILOSX";
+ SLSW, AccessPermission:Busy, desc="local WB request, was SLS";
+ OLSW, AccessPermission:Busy, desc="local WB request, was OLS";
+ ILSW, AccessPermission:Busy, desc="local WB request, was ILS";
+ IW, AccessPermission:Busy, desc="local WB request from only sharer, was ILS";
+ OW, AccessPermission:Busy, desc="local WB request from only sharer, was OLS";
+ SW, AccessPermission:Busy, desc="local WB request from only sharer, was SLS";
+ OXW, AccessPermission:Busy, desc="local WB request from only sharer, was OLSX";
+ OLSXW, AccessPermission:Busy, desc="local WB request from sharer, was OLSX";
+ ILXW, AccessPermission:Busy, desc="local WB request, was ILX";
+
+ IFLS, AccessPermission:Busy, desc="Blocked, forwarded local GETS to _some_ local sharer";
+ IFLO, AccessPermission:Busy, desc="Blocked, forwarded local GETS to local owner";
+ IFLOX, AccessPermission:Busy, desc="Blocked, forwarded local GETS to local owner but chip is exclusive";
+ IFLOXX, AccessPermission:Busy, desc="Blocked, forwarded local GETX to local owner/exclusive, chip is exclusive";
+ IFLOSX, AccessPermission:Busy, desc="Blocked, forwarded local GETS to local owner w/ other sharers, chip is exclusive";
+ IFLXO, AccessPermission:Busy, desc="Blocked, forwarded local GETX to local owner with other sharers, chip is exclusive";
+
+ IGS, AccessPermission:Busy, desc="Semi-blocked, issued local GETS to directory";
+ IGM, AccessPermission:Busy, desc="Blocked, issued local GETX to directory. Need global acks and data";
+ IGMLS, AccessPermission:Busy, desc="Blocked, issued local GETX to directory but may need to INV local sharers";
+ IGMO, AccessPermission:Busy, desc="Blocked, have data for local GETX but need all acks";
+ IGMIO, AccessPermission:Busy, desc="Blocked, issued local GETX, local owner with possible local sharer, may need to INV";
+ OGMIO, AccessPermission:Busy, desc="Blocked, issued local GETX, was owner, may need to INV";
+ IGMIOF, AccessPermission:Busy, desc="Blocked, issued local GETX, local owner, waiting for global acks, got Fwd_GETX";
+ IGMIOFS, AccessPermission:Busy, desc="Blocked, issued local GETX, local owner, waiting for global acks, got Fwd_GETS";
+ OGMIOF, AccessPermission:Busy, desc="Blocked, issued local GETX, was owner, waiting for global acks, got Fwd_GETX";
+
+ II, AccessPermission:Busy, desc="Blocked, handling invalidations";
+ MM, AccessPermission:Busy, desc="Blocked, was M satisfying local GETX";
+ SS, AccessPermission:Busy, desc="Blocked, was S satisfying local GETS";
+ OO, AccessPermission:Busy, desc="Blocked, was O satisfying local GETS";
+ OLSS, AccessPermission:Busy, desc="Blocked, satisfying local GETS";
+ OLSXS, AccessPermission:Busy, desc="Blocked, satisfying local GETS";
+ SLSS, AccessPermission:Busy, desc="Blocked, satisfying local GETS";
+
+ OI, AccessPermission:Busy, desc="Blocked, doing writeback, was O";
+ MI, AccessPermission:Busy, desc="Blocked, doing writeback, was M";
+ 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";
}
// EVENTS
@@ -486,9 +486,6 @@ machine(L2Cache, "Token protocol")
else {
cache_entry.CacheState := state;
}
-
- // Set permission
- cache_entry.changePermission(AccessPermission:Read_Only);
}
else if (localDirectory.isTagPresent(addr)) {
localDirectory[addr].DirState := state;
diff --git a/src/mem/protocol/MOESI_CMP_directory-dir.sm b/src/mem/protocol/MOESI_CMP_directory-dir.sm
index 19b69c64c..55afa7161 100644
--- a/src/mem/protocol/MOESI_CMP_directory-dir.sm
+++ b/src/mem/protocol/MOESI_CMP_directory-dir.sm
@@ -48,28 +48,28 @@ machine(Directory, "Directory protocol")
// STATES
- enumeration(State, desc="Directory states", default="Directory_State_I") {
+ state_declaration(State, desc="Directory states", default="Directory_State_I") {
// Base states
- I, desc="Invalid";
- S, desc="Shared";
- O, desc="Owner";
- M, desc="Modified";
-
- IS, desc="Blocked, was in idle";
- SS, desc="Blocked, was in shared";
- OO, desc="Blocked, was in owned";
- MO, desc="Blocked, going to owner or maybe modified";
- MM, desc="Blocked, going to modified";
- MM_DMA, desc="Blocked, going to I";
-
- MI, desc="Blocked on a writeback";
- MIS, desc="Blocked on a writeback, but don't remove from sharers when received";
- OS, desc="Blocked on a writeback";
- OSS, desc="Blocked on a writeback, but don't remove from sharers when received";
-
- XI_M, desc="In a stable state, going to I, waiting for the memory controller";
- XI_U, desc="In a stable state, going to I, waiting for an unblock";
- OI_D, desc="In O, going to I, waiting for data";
+ I, AccessPermission:Invalid, desc="Invalid";
+ S, AccessPermission:Read_Only, desc="Shared";
+ O, AccessPermission:Read_Only, desc="Owner";
+ M, AccessPermission:Read_Write, desc="Modified";
+
+ IS, AccessPermission:Busy, desc="Blocked, was in idle";
+ SS, AccessPermission:Read_Only, desc="Blocked, was in shared";
+ OO, AccessPermission:Read_Only, desc="Blocked, was in owned";
+ MO, AccessPermission:Read_Only, desc="Blocked, going to owner or maybe modified";
+ MM, AccessPermission:Read_Only, desc="Blocked, going to modified";
+ MM_DMA, AccessPermission:Busy, desc="Blocked, going to I";
+
+ MI, AccessPermission:Busy, desc="Blocked on a writeback";
+ MIS, AccessPermission:Busy, desc="Blocked on a writeback, but don't remove from sharers when received";
+ OS, AccessPermission:Busy, desc="Blocked on a writeback";
+ OSS, AccessPermission:Busy, desc="Blocked on a writeback, but don't remove from sharers when received";
+
+ 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";
}
// Events
diff --git a/src/mem/protocol/MOESI_CMP_directory-dma.sm b/src/mem/protocol/MOESI_CMP_directory-dma.sm
index b129757b8..43503ee25 100644
--- a/src/mem/protocol/MOESI_CMP_directory-dma.sm
+++ b/src/mem/protocol/MOESI_CMP_directory-dma.sm
@@ -13,10 +13,10 @@ machine(DMA, "DMA Controller")
MessageBuffer reqToDir, network="To", virtual_network="1", ordered="false";
MessageBuffer respToDir, network="To", virtual_network="2", ordered="false";
- enumeration(State, desc="DMA states", default="DMA_State_READY") {
- READY, desc="Ready to accept a new request";
- BUSY_RD, desc="Busy: currently processing a request";
- BUSY_WR, desc="Busy: currently processing a request";
+ state_declaration(State, desc="DMA states", default="DMA_State_READY") {
+ READY, AccessPermission:Invalid, desc="Ready to accept a new request";
+ BUSY_RD, AccessPermission:Busy, desc="Busy: currently processing a request";
+ BUSY_WR, AccessPermission:Busy, desc="Busy: currently processing a request";
}
enumeration(Event, desc="DMA events") {
diff --git a/src/mem/protocol/MOESI_CMP_token-L1cache.sm b/src/mem/protocol/MOESI_CMP_token-L1cache.sm
index 226f21374..160208aac 100644
--- a/src/mem/protocol/MOESI_CMP_token-L1cache.sm
+++ b/src/mem/protocol/MOESI_CMP_token-L1cache.sm
@@ -63,29 +63,29 @@ machine(L1Cache, "Token protocol")
MessageBuffer requestToL1Cache, network="From", virtual_network="1", ordered="false";
// STATES
- enumeration(State, desc="Cache states", default="L1Cache_State_I") {
+ state_declaration(State, desc="Cache states", default="L1Cache_State_I") {
// Base states
- NP, "NP", desc="Not Present";
- I, "I", desc="Idle";
- S, "S", desc="Shared";
- O, "O", desc="Owned";
- M, "M", desc="Modified (dirty)";
- MM, "MM", desc="Modified (dirty and locally modified)";
- M_W, "M^W", desc="Modified (dirty), waiting";
- MM_W, "MM^W", desc="Modified (dirty and locally modified), waiting";
+ NP, AccessPermission:Invalid, "NP", desc="Not Present";
+ I, AccessPermission:Invalid, "I", desc="Idle";
+ S, AccessPermission:Read_Only, "S", desc="Shared";
+ O, AccessPermission:Read_Only, "O", desc="Owned";
+ M, AccessPermission:Read_Only, "M", desc="Modified (dirty)";
+ MM, AccessPermission:Read_Write, "MM", desc="Modified (dirty and locally modified)";
+ M_W, AccessPermission:Read_Only, "M^W", desc="Modified (dirty), waiting";
+ MM_W, AccessPermission:Read_Write, "MM^W", desc="Modified (dirty and locally modified), waiting";
// Transient States
- IM, "IM", desc="Issued GetX";
- SM, "SM", desc="Issued GetX, we still have an old copy of the line";
- OM, "OM", desc="Issued GetX, received data";
- IS, "IS", desc="Issued GetS";
+ IM, AccessPermission:Busy, "IM", desc="Issued GetX";
+ SM, AccessPermission:Read_Only, "SM", desc="Issued GetX, we still have an old copy of the line";
+ OM, AccessPermission:Read_Only, "OM", desc="Issued GetX, received data";
+ IS, AccessPermission:Busy, "IS", desc="Issued GetS";
// Locked states
- I_L, "I^L", desc="Invalid, Locked";
- S_L, "S^L", desc="Shared, Locked";
- IM_L, "IM^L", desc="Invalid, Locked, trying to go to Modified";
- SM_L, "SM^L", desc="Shared, Locked, trying to go to Modified";
- IS_L, "IS^L", desc="Invalid, Locked, trying to go to Shared";
+ I_L, AccessPermission:Busy, "I^L", desc="Invalid, Locked";
+ S_L, AccessPermission:Busy, "S^L", desc="Shared, Locked";
+ IM_L, AccessPermission:Busy, "IM^L", desc="Invalid, Locked, trying to go to Modified";
+ SM_L, AccessPermission:Busy, "SM^L", desc="Shared, Locked, trying to go to Modified";
+ IS_L, AccessPermission:Busy, "IS^L", desc="Invalid, Locked, trying to go to Shared";
}
// EVENTS
@@ -336,23 +336,6 @@ machine(L1Cache, "Token protocol")
}
cache_entry.CacheState := state;
-
- // Set permission
- if (state == State:MM ||
- state == State:MM_W) {
- cache_entry.changePermission(AccessPermission:Read_Write);
- } else if ((state == State:S) ||
- (state == State:O) ||
- (state == State:M) ||
- (state == State:M_W) ||
- (state == State:SM) ||
- (state == State:S_L) ||
- (state == State:SM_L) ||
- (state == State:OM)) {
- cache_entry.changePermission(AccessPermission:Read_Only);
- } else {
- cache_entry.changePermission(AccessPermission:Invalid);
- }
}
}
diff --git a/src/mem/protocol/MOESI_CMP_token-L2cache.sm b/src/mem/protocol/MOESI_CMP_token-L2cache.sm
index c23f98f9a..e685984c5 100644
--- a/src/mem/protocol/MOESI_CMP_token-L2cache.sm
+++ b/src/mem/protocol/MOESI_CMP_token-L2cache.sm
@@ -62,17 +62,17 @@ machine(L2Cache, "Token protocol")
MessageBuffer L1RequestToL2Cache, network="From", virtual_network="1", ordered="false";
// STATES
- enumeration(State, desc="L2 Cache states", default="L2Cache_State_I") {
+ state_declaration(State, desc="L2 Cache states", default="L2Cache_State_I") {
// Base states
- NP, desc="Not Present";
- I, desc="Idle";
- S, desc="Shared, not present in any local L1s";
- O, desc="Owned, not present in any L1s";
- M, desc="Modified, not present in any L1s";
+ NP, AccessPermission:Invalid, desc="Not Present";
+ I, AccessPermission:Invalid, desc="Idle";
+ S, AccessPermission:Read_Only, desc="Shared, not present in any local L1s";
+ O, AccessPermission:Read_Only, desc="Owned, not present in any L1s";
+ M, AccessPermission:Read_Write, desc="Modified, not present in any L1s";
// Locked states
- I_L, "I^L", desc="Invalid, Locked";
- S_L, "S^L", desc="Shared, Locked";
+ I_L, AccessPermission:Busy, "I^L", desc="Invalid, Locked";
+ S_L, AccessPermission:Busy, "S^L", desc="Shared, Locked";
}
// EVENTS
@@ -208,17 +208,6 @@ machine(L2Cache, "Token protocol")
}
cache_entry.CacheState := state;
-
- // Set permission
- if (state == State:I) {
- cache_entry.changePermission(AccessPermission:Invalid);
- } else if (state == State:S || state == State:O ) {
- cache_entry.changePermission(AccessPermission:Read_Only);
- } else if (state == State:M ) {
- cache_entry.changePermission(AccessPermission:Read_Write);
- } else {
- cache_entry.changePermission(AccessPermission:Invalid);
- }
}
}
diff --git a/src/mem/protocol/MOESI_CMP_token-dir.sm b/src/mem/protocol/MOESI_CMP_token-dir.sm
index c77d46bbe..14a2f0fb2 100644
--- a/src/mem/protocol/MOESI_CMP_token-dir.sm
+++ b/src/mem/protocol/MOESI_CMP_token-dir.sm
@@ -52,30 +52,30 @@ machine(Directory, "Token protocol")
MessageBuffer dmaRequestToDir, network="From", virtual_network="0", ordered="true";
// STATES
- enumeration(State, desc="Directory states", default="Directory_State_O") {
+ state_declaration(State, desc="Directory states", default="Directory_State_O") {
// Base states
- O, desc="Owner";
- NO, desc="Not Owner";
- L, desc="Locked";
+ O, AccessPermission:Read_Only, desc="Owner, memory has valid data, but not necessarily all the tokens";
+ NO, AccessPermission:Invalid, desc="Not Owner";
+ L, AccessPermission:Busy, desc="Locked";
// Memory wait states - can block all messages including persistent requests
- O_W, desc="transitioning to Owner, waiting for memory write";
- L_O_W, desc="transitioning to Locked, waiting for memory read, could eventually return to O";
- L_NO_W, desc="transitioning to Locked, waiting for memory read, eventually return to NO";
- DR_L_W, desc="transitioning to Locked underneath a DMA read, waiting for memory data";
- DW_L_W, desc="transitioning to Locked underneath a DMA write, waiting for memory ack";
- NO_W, desc="transitioning to Not Owner, waiting for memory read";
- O_DW_W, desc="transitioning to Owner, waiting for memory before DMA ack";
- O_DR_W, desc="transitioning to Owner, waiting for memory before DMA data";
+ O_W, AccessPermission:Busy, desc="transitioning to Owner, waiting for memory write";
+ L_O_W, AccessPermission:Busy, desc="transitioning to Locked, waiting for memory read, could eventually return to O";
+ L_NO_W, AccessPermission:Busy, desc="transitioning to Locked, waiting for memory read, eventually return to NO";
+ DR_L_W, AccessPermission:Busy, desc="transitioning to Locked underneath a DMA read, waiting for memory data";
+ DW_L_W, AccessPermission:Busy, desc="transitioning to Locked underneath a DMA write, waiting for memory ack";
+ NO_W, AccessPermission:Busy, desc="transitioning to Not Owner, waiting for memory read";
+ O_DW_W, AccessPermission:Busy, desc="transitioning to Owner, waiting for memory before DMA ack";
+ O_DR_W, AccessPermission:Busy, desc="transitioning to Owner, waiting for memory before DMA data";
// DMA request transient states - must respond to persistent requests
- O_DW, desc="issued GETX for DMA write, waiting for all tokens";
- NO_DW, desc="issued GETX for DMA write, waiting for all tokens";
- NO_DR, desc="issued GETS for DMA read, waiting for data";
+ O_DW, AccessPermission:Busy, desc="issued GETX for DMA write, waiting for all tokens";
+ NO_DW, AccessPermission:Busy, desc="issued GETX for DMA write, waiting for all tokens";
+ NO_DR, AccessPermission:Busy, desc="issued GETS for DMA read, waiting for data";
// DMA request in progress - competing with a CPU persistent request
- DW_L, desc="issued GETX for DMA write, CPU persistent request must complete first";
- DR_L, desc="issued GETS for DMA read, CPU persistent request must complete first";
+ DW_L, AccessPermission:Busy, desc="issued GETX for DMA write, CPU persistent request must complete first";
+ DR_L, AccessPermission:Busy, desc="issued GETS for DMA read, CPU persistent request must complete first";
}
diff --git a/src/mem/protocol/MOESI_CMP_token-dma.sm b/src/mem/protocol/MOESI_CMP_token-dma.sm
index 666117a10..e80f91995 100644
--- a/src/mem/protocol/MOESI_CMP_token-dma.sm
+++ b/src/mem/protocol/MOESI_CMP_token-dma.sm
@@ -35,10 +35,10 @@ machine(DMA, "DMA Controller")
MessageBuffer responseFromDir, network="From", virtual_network="5", ordered="true", no_vector="true";
MessageBuffer reqToDirectory, network="To", virtual_network="0", ordered="false", no_vector="true";
- enumeration(State, desc="DMA states", default="DMA_State_READY") {
- READY, desc="Ready to accept a new request";
- BUSY_RD, desc="Busy: currently processing a request";
- BUSY_WR, desc="Busy: currently processing a request";
+ state_declaration(State, desc="DMA states", default="DMA_State_READY") {
+ READY, AccessPermission:Invalid, desc="Ready to accept a new request";
+ BUSY_RD, AccessPermission:Busy, desc="Busy: currently processing a request";
+ BUSY_WR, AccessPermission:Busy, desc="Busy: currently processing a request";
}
enumeration(Event, desc="DMA events") {
diff --git a/src/mem/protocol/MOESI_hammer-cache.sm b/src/mem/protocol/MOESI_hammer-cache.sm
index 9592e3881..05d74038b 100644
--- a/src/mem/protocol/MOESI_hammer-cache.sm
+++ b/src/mem/protocol/MOESI_hammer-cache.sm
@@ -54,31 +54,31 @@ machine(L1Cache, "AMD Hammer-like protocol")
// STATES
- enumeration(State, desc="Cache states", default="L1Cache_State_I") {
+ state_declaration(State, desc="Cache states", default="L1Cache_State_I") {
// Base states
- I, desc="Idle";
- S, desc="Shared";
- O, desc="Owned";
- M, desc="Modified (dirty)";
- MM, desc="Modified (dirty and locally modified)";
+ I, AccessPermission:Invalid, desc="Idle";
+ S, AccessPermission:Read_Only, desc="Shared";
+ O, AccessPermission:Read_Only, desc="Owned";
+ M, AccessPermission:Read_Only, desc="Modified (dirty)";
+ MM, AccessPermission:Read_Write, desc="Modified (dirty and locally modified)";
// Transient States
- IM, "IM", desc="Issued GetX";
- SM, "SM", desc="Issued GetX, we still have an old copy of the line";
- OM, "OM", desc="Issued GetX, received data";
- ISM, "ISM", desc="Issued GetX, received data, waiting for all acks";
- M_W, "M^W", desc="Issued GetS, received exclusive data";
- MM_W, "MM^W", desc="Issued GetX, received exclusive data";
- IS, "IS", desc="Issued GetS";
- SS, "SS", desc="Issued GetS, received data, waiting for all acks";
- OI, "OI", desc="Issued PutO, waiting for ack";
- MI, "MI", desc="Issued PutX, waiting for ack";
- II, "II", desc="Issued PutX/O, saw Other_GETS or Other_GETX, waiting for ack";
- IT, "IT", desc="Invalid block transferring to L1";
- ST, "ST", desc="S block transferring to L1";
- OT, "OT", desc="O block transferring to L1";
- MT, "MT", desc="M block transferring to L1";
- MMT, "MMT", desc="MM block transferring to L1";
+ IM, AccessPermission:Busy, "IM", desc="Issued GetX";
+ SM, AccessPermission:Read_Only, "SM", desc="Issued GetX, we still have a valid copy of the line";
+ OM, AccessPermission:Read_Only, "OM", desc="Issued GetX, received data";
+ ISM, AccessPermission:Read_Only, "ISM", desc="Issued GetX, received valid data, waiting for all acks";
+ M_W, AccessPermission:Read_Only, "M^W", desc="Issued GetS, received exclusive data";
+ MM_W, AccessPermission:Read_Write, "MM^W", desc="Issued GetX, received exclusive data";
+ IS, AccessPermission:Busy, "IS", desc="Issued GetS";
+ SS, AccessPermission:Read_Only, "SS", desc="Issued GetS, received data, waiting for all acks";
+ 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";
+ MMT, AccessPermission:Busy, "MMT", desc="MM block transferring to L1";
}
// EVENTS
@@ -209,23 +209,6 @@ machine(L1Cache, "AMD Hammer-like protocol")
if (is_valid(cache_entry)) {
cache_entry.CacheState := state;
-
- // Set permission
- if ((state == State:MM) ||
- (state == State:MM_W)) {
- cache_entry.changePermission(AccessPermission:Read_Write);
- } else if (state == State:S ||
- state == State:O ||
- state == State:M ||
- state == State:M_W ||
- state == State:SM ||
- state == State:ISM ||
- state == State:OM ||
- state == State:SS) {
- cache_entry.changePermission(AccessPermission:Read_Only);
- } else {
- cache_entry.changePermission(AccessPermission:Invalid);
- }
}
}
diff --git a/src/mem/protocol/MOESI_hammer-dir.sm b/src/mem/protocol/MOESI_hammer-dir.sm
index 67c375fbc..8f6cb14b7 100644
--- a/src/mem/protocol/MOESI_hammer-dir.sm
+++ b/src/mem/protocol/MOESI_hammer-dir.sm
@@ -57,37 +57,37 @@ machine(Directory, "AMD Hammer-like protocol")
MessageBuffer dmaRequestToDir, network="From", virtual_network="0", ordered="true";
// STATES
- enumeration(State, desc="Directory states", default="Directory_State_E") {
+ state_declaration(State, desc="Directory states", default="Directory_State_E") {
// Base states
- NX, desc="Not Owner, probe filter entry exists, block in O at Owner";
- NO, desc="Not Owner, probe filter entry exists, block in E/M at Owner";
- S, desc="Data clean, probe filter entry exists pointing to the current owner";
- O, desc="Data clean, probe filter entry exists";
- E, desc="Exclusive Owner, no probe filter entry";
-
- O_R, desc="Was data Owner, replacing probe filter entry";
- S_R, desc="Was Not Owner or Sharer, replacing probe filter entry";
- NO_R, desc="Was Not Owner or Sharer, replacing probe filter entry";
-
- NO_B, "NO^B", desc="Not Owner, Blocked";
- NO_B_X, "NO^B", desc="Not Owner, Blocked, next queued request GETX";
- NO_B_S, "NO^B", desc="Not Owner, Blocked, next queued request GETS";
- NO_B_S_W, "NO^B", desc="Not Owner, Blocked, forwarded merged GETS, waiting for responses";
- O_B, "O^B", desc="Owner, Blocked";
- NO_B_W, desc="Not Owner, Blocked, waiting for Dram";
- O_B_W, desc="Owner, Blocked, waiting for Dram";
- NO_W, desc="Not Owner, waiting for Dram";
- O_W, desc="Owner, waiting for Dram";
- NO_DW_B_W, desc="Not Owner, Dma Write waiting for Dram and cache responses";
- NO_DR_B_W, desc="Not Owner, Dma Read waiting for Dram and cache responses";
- NO_DR_B_D, desc="Not Owner, Dma Read waiting for cache responses including dirty data";
- NO_DR_B, desc="Not Owner, Dma Read waiting for cache responses";
- NO_DW_W, desc="Not Owner, Dma Write waiting for Dram";
- O_DR_B_W, desc="Owner, Dma Read waiting for Dram and cache responses";
- O_DR_B, desc="Owner, Dma Read waiting for cache responses";
- WB, desc="Blocked on a writeback";
- WB_O_W, desc="Blocked on memory write, will go to O";
- WB_E_W, desc="Blocked on memory write, will go to E";
+ NX, AccessPermission:Invalid, desc="Not Owner, probe filter entry exists, block in O at Owner";
+ NO, AccessPermission:Invalid, desc="Not Owner, probe filter entry exists, block in E/M at Owner";
+ S, AccessPermission:Read_Only, desc="Data clean, probe filter entry exists pointing to the current owner";
+ O, AccessPermission:Read_Only, desc="Data clean, probe filter entry exists";
+ E, AccessPermission:Read_Write, desc="Exclusive Owner, no probe filter entry";
+
+ O_R, AccessPermission:Read_Only, desc="Was data Owner, replacing probe filter entry";
+ S_R, AccessPermission:Read_Only, desc="Was Not Owner or Sharer, replacing probe filter entry";
+ NO_R, AccessPermission:Invalid, desc="Was Not Owner or Sharer, replacing probe filter entry";
+
+ NO_B, AccessPermission:Invalid, "NO^B", desc="Not Owner, Blocked";
+ NO_B_X, AccessPermission:Invalid, "NO^B", desc="Not Owner, Blocked, next queued request GETX";
+ NO_B_S, AccessPermission:Invalid, "NO^B", desc="Not Owner, Blocked, next queued request GETS";
+ NO_B_S_W, AccessPermission:Invalid, "NO^B", desc="Not Owner, Blocked, forwarded merged GETS, waiting for responses";
+ O_B, AccessPermission:Invalid, "O^B", desc="Owner, Blocked";
+ NO_B_W, AccessPermission:Invalid, desc="Not Owner, Blocked, waiting for Dram";
+ O_B_W, AccessPermission:Invalid, desc="Owner, Blocked, waiting for Dram";
+ NO_W, AccessPermission:Invalid, desc="Not Owner, waiting for Dram";
+ O_W, AccessPermission:Invalid, desc="Owner, waiting for Dram";
+ NO_DW_B_W, AccessPermission:Invalid, desc="Not Owner, Dma Write waiting for Dram and cache responses";
+ NO_DR_B_W, AccessPermission:Invalid, desc="Not Owner, Dma Read waiting for Dram and cache responses";
+ NO_DR_B_D, AccessPermission:Invalid, desc="Not Owner, Dma Read waiting for cache responses including dirty data";
+ NO_DR_B, AccessPermission:Invalid, desc="Not Owner, Dma Read waiting for cache responses";
+ NO_DW_W, AccessPermission:Invalid, desc="Not Owner, Dma Write waiting for Dram";
+ O_DR_B_W, AccessPermission:Invalid, desc="Owner, Dma Read waiting for Dram and cache responses";
+ O_DR_B, AccessPermission:Invalid, desc="Owner, Dma Read waiting for cache responses";
+ WB, AccessPermission:Invalid, desc="Blocked on a writeback";
+ WB_O_W, AccessPermission:Invalid, desc="Blocked on memory write, will go to O";
+ WB_E_W, AccessPermission:Invalid, desc="Blocked on memory write, will go to E";
}
// Events
diff --git a/src/mem/protocol/MOESI_hammer-dma.sm b/src/mem/protocol/MOESI_hammer-dma.sm
index dbb5ffe68..d80c55c73 100644
--- a/src/mem/protocol/MOESI_hammer-dma.sm
+++ b/src/mem/protocol/MOESI_hammer-dma.sm
@@ -35,10 +35,12 @@ machine(DMA, "DMA Controller")
MessageBuffer responseFromDir, network="From", virtual_network="1", ordered="true", no_vector="true";
MessageBuffer reqToDirectory, network="To", virtual_network="0", ordered="false", no_vector="true";
- enumeration(State, desc="DMA states", default="DMA_State_READY") {
- READY, desc="Ready to accept a new request";
- BUSY_RD, desc="Busy: currently processing a request";
- BUSY_WR, desc="Busy: currently processing a request";
+ state_declaration(State,
+ desc="DMA states",
+ default="DMA_State_READY") {
+ READY, AccessPermission:Invalid, desc="Ready to accept a new request";
+ BUSY_RD, AccessPermission:Busy, desc="Busy: currently processing a request";
+ BUSY_WR, AccessPermission:Busy, desc="Busy: currently processing a request";
}
enumeration(Event, desc="DMA events") {
diff --git a/src/mem/protocol/RubySlicc_Types.sm b/src/mem/protocol/RubySlicc_Types.sm
index 1d68768e4..f8783230e 100644
--- a/src/mem/protocol/RubySlicc_Types.sm
+++ b/src/mem/protocol/RubySlicc_Types.sm
@@ -117,9 +117,7 @@ external_type(DirectoryMemory) {
void invalidateBlock(Address);
}
-external_type(AbstractCacheEntry, primitive="yes") {
- void changePermission(AccessPermission);
-}
+external_type(AbstractCacheEntry, primitive="yes");
external_type(CacheMemory) {
bool cacheAvail(Address);
diff --git a/src/mem/ruby/slicc_interface/AbstractCacheEntry.cc b/src/mem/ruby/slicc_interface/AbstractCacheEntry.cc
index d53697c76..137a6c950 100644
--- a/src/mem/ruby/slicc_interface/AbstractCacheEntry.cc
+++ b/src/mem/ruby/slicc_interface/AbstractCacheEntry.cc
@@ -30,8 +30,8 @@
AbstractCacheEntry::AbstractCacheEntry()
{
- m_Address.setAddress(0);
m_Permission = AccessPermission_NotPresent;
+ m_Address.setAddress(0);
m_locked = -1;
}
@@ -39,16 +39,10 @@ AbstractCacheEntry::~AbstractCacheEntry()
{
}
-AccessPermission
-AbstractCacheEntry::getPermission() const
-{
- return m_Permission;
-}
-
void
AbstractCacheEntry::changePermission(AccessPermission new_perm)
{
- m_Permission = new_perm;
+ AbstractEntry::changePermission(new_perm);
if ((new_perm == AccessPermission_Invalid) ||
(new_perm == AccessPermission_NotPresent)) {
m_locked = -1;
diff --git a/src/mem/ruby/slicc_interface/AbstractCacheEntry.hh b/src/mem/ruby/slicc_interface/AbstractCacheEntry.hh
index 87c96a9cb..69333f481 100644
--- a/src/mem/ruby/slicc_interface/AbstractCacheEntry.hh
+++ b/src/mem/ruby/slicc_interface/AbstractCacheEntry.hh
@@ -48,15 +48,12 @@ class AbstractCacheEntry : public AbstractEntry
AbstractCacheEntry();
virtual ~AbstractCacheEntry() = 0;
- // Get/Set permission of cache entry
- AccessPermission getPermission() const;
+ // Get/Set permission of the entry
void changePermission(AccessPermission new_perm);
Address m_Address; // Address of this block, required by CacheMemory
Time m_LastRef; // Last time this block was referenced, required
// by CacheMemory
- AccessPermission m_Permission; // Access permission for this
- // block, required by CacheMemory
int m_locked; // Holds info whether the address is locked,
// required for implementing LL/SC
};
diff --git a/src/mem/ruby/slicc_interface/AbstractEntry.cc b/src/mem/ruby/slicc_interface/AbstractEntry.cc
index d66258eef..51f16df6a 100644
--- a/src/mem/ruby/slicc_interface/AbstractEntry.cc
+++ b/src/mem/ruby/slicc_interface/AbstractEntry.cc
@@ -30,8 +30,21 @@
AbstractEntry::AbstractEntry()
{
+ m_Permission = AccessPermission_NotPresent;
}
AbstractEntry::~AbstractEntry()
{
}
+
+AccessPermission
+AbstractEntry::getPermission() const
+{
+ return m_Permission;
+}
+
+void
+AbstractEntry::changePermission(AccessPermission new_perm)
+{
+ m_Permission = new_perm;
+}
diff --git a/src/mem/ruby/slicc_interface/AbstractEntry.hh b/src/mem/ruby/slicc_interface/AbstractEntry.hh
index 19852fbe9..6752bf6c4 100644
--- a/src/mem/ruby/slicc_interface/AbstractEntry.hh
+++ b/src/mem/ruby/slicc_interface/AbstractEntry.hh
@@ -43,11 +43,18 @@ class AbstractEntry
AbstractEntry();
virtual ~AbstractEntry() = 0;
+ // Get/Set permission of the entry
+ AccessPermission getPermission() const;
+ void changePermission(AccessPermission new_perm);
+
// The methods below are those called by ruby runtime, add when it
// is absolutely necessary and should all be virtual function.
virtual DataBlock& getDataBlk() = 0;
virtual void print(std::ostream& out) const = 0;
+
+ AccessPermission m_Permission; // Access permission for this
+ // block, required by CacheMemory
};
inline std::ostream&
diff --git a/src/mem/slicc/ast/StateDeclAST.py b/src/mem/slicc/ast/StateDeclAST.py
new file mode 100644
index 000000000..a1bbd74ae
--- /dev/null
+++ b/src/mem/slicc/ast/StateDeclAST.py
@@ -0,0 +1,79 @@
+# Copyright (c) 2011 Advanced Micro Devices, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.DeclAST import DeclAST
+from slicc.symbols import Func, Type
+
+class StateDeclAST(DeclAST):
+ def __init__(self, slicc, type_ast, pairs, states):
+ super(StateDeclAST, self).__init__(slicc, pairs)
+
+ self.type_ast = type_ast
+ self.states = states
+
+ def __repr__(self):
+ return "[StateDecl: %s]" % (self.type_ast)
+
+ def files(self, parent=None):
+ if "external" in self:
+ return set()
+
+ if parent:
+ ident = "%s_%s" % (parent, self.type_ast.ident)
+ else:
+ ident = self.type_ast.ident
+ s = set(("%s.hh" % ident, "%s.cc" % ident))
+ return s
+
+ def generate(self):
+ ident = str(self.type_ast)
+
+ # Make the new type
+ t = Type(self.symtab, ident, self.location, self.pairs,
+ self.state_machine)
+ self.symtab.newSymbol(t)
+
+ # Add all of the states of the type to it
+ for state in self.states:
+ state.generate(t)
+
+ # Add the implicit State_to_string method - FIXME, this is a bit dirty
+ func_id = "%s_to_string" % t.c_ident
+
+ pairs = { "external" : "yes" }
+ func = Func(self.symtab, func_id, self.location,
+ self.symtab.find("std::string", Type), [ t ], [], "",
+ pairs, None)
+ self.symtab.newSymbol(func)
+
+ # Add the State_to_permission method
+ func_id = "%s_to_permission" % t.c_ident
+
+ pairs = { "external" : "yes" }
+ func = Func(self.symtab, func_id, self.location,
+ self.symtab.find("AccessPermission", Type), [ t ], [], "",
+ pairs, None)
+ self.symtab.newSymbol(func)
diff --git a/src/mem/slicc/ast/TypeFieldEnumAST.py b/src/mem/slicc/ast/TypeFieldEnumAST.py
index 138fff793..398604550 100644
--- a/src/mem/slicc/ast/TypeFieldEnumAST.py
+++ b/src/mem/slicc/ast/TypeFieldEnumAST.py
@@ -39,6 +39,9 @@ class TypeFieldEnumAST(TypeFieldAST):
return "[TypeFieldEnum: %r]" % self.field_id
def generate(self, type):
+ if str(type) == "State":
+ self.error("States must in a State Declaration, not a normal enum.")
+
# Add enumeration
if not type.enumAdd(self.field_id, self.pairs_ast.pairs):
self.error("Duplicate enumeration: %s:%s" % (type, self.field_id))
@@ -46,12 +49,6 @@ class TypeFieldEnumAST(TypeFieldAST):
# Fill machine info
machine = self.symtab.state_machine
- if str(type) == "State":
- if not machine:
- self.error("State declaration not part of a machine.")
- s = State(self.symtab, self.field_id, self.location, self.pairs)
- machine.addState(s)
-
if str(type) == "Event":
if not machine:
self.error("Event declaration not part of a machine.")
diff --git a/src/mem/slicc/ast/TypeFieldStateAST.py b/src/mem/slicc/ast/TypeFieldStateAST.py
new file mode 100644
index 000000000..aafa241dd
--- /dev/null
+++ b/src/mem/slicc/ast/TypeFieldStateAST.py
@@ -0,0 +1,61 @@
+# Copyright (c) 2011 Advanced Micro Devices, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.TypeFieldAST import TypeFieldAST
+from slicc.symbols import Event, State
+
+class TypeFieldStateAST(TypeFieldAST):
+ def __init__(self, slicc, field_id, perm_ast, pairs_ast):
+ super(TypeFieldStateAST, self).__init__(slicc, pairs_ast)
+
+ self.field_id = field_id
+ self.perm_ast = perm_ast
+ if not (perm_ast.type_ast.ident == "AccessPermission"):
+ self.error("AccessPermission enum value must be specified")
+ self.pairs_ast = pairs_ast
+
+ def __repr__(self):
+ return "[TypeFieldState: %r]" % self.field_id
+
+ def generate(self, type):
+ if not str(type) == "State":
+ self.error("State Declaration must be of type State.")
+
+ # Add enumeration
+ if not type.enumAdd(self.field_id, self.pairs_ast.pairs):
+ self.error("Duplicate enumeration: %s:%s" % (type, self.field_id))
+
+ # Fill machine info
+ machine = self.symtab.state_machine
+
+ if not machine:
+ self.error("State declaration not part of a machine.")
+ s = State(self.symtab, self.field_id, self.location, self.pairs)
+ machine.addState(s)
+
+ type.statePermPairAdd(s, self.perm_ast.value)
+
+
diff --git a/src/mem/slicc/ast/__init__.py b/src/mem/slicc/ast/__init__.py
index 4af6c2036..c0f54a9a3 100644
--- a/src/mem/slicc/ast/__init__.py
+++ b/src/mem/slicc/ast/__init__.py
@@ -61,6 +61,7 @@ from slicc.ast.PairListAST import *
from slicc.ast.PeekStatementAST import *
from slicc.ast.ReturnStatementAST import *
from slicc.ast.StallAndWaitStatementAST import *
+from slicc.ast.StateDeclAST import *
from slicc.ast.StatementAST import *
from slicc.ast.StatementListAST import *
from slicc.ast.StaticCastAST import *
@@ -71,6 +72,7 @@ from slicc.ast.TypeFieldAST import *
from slicc.ast.TypeFieldEnumAST import *
from slicc.ast.TypeFieldMemberAST import *
from slicc.ast.TypeFieldMethodAST import *
+from slicc.ast.TypeFieldStateAST import *
from slicc.ast.VarExprAST import *
from slicc.ast.WakeUpAllDependentsStatementAST import *
from slicc.ast.WakeUpDependentsStatementAST import *
diff --git a/src/mem/slicc/parser.py b/src/mem/slicc/parser.py
index 823e08819..448954e63 100644
--- a/src/mem/slicc/parser.py
+++ b/src/mem/slicc/parser.py
@@ -156,6 +156,7 @@ class SLICC(Grammar):
'structure' : 'STRUCT',
'external_type' : 'EXTERN_TYPE',
'enumeration' : 'ENUM',
+ 'state_declaration' : 'STATE_DECL',
'peek' : 'PEEK',
'stall_and_wait' : 'STALL_AND_WAIT',
'wake_up_dependents' : 'WAKE_UP_DEPENDENTS',
@@ -329,6 +330,12 @@ class SLICC(Grammar):
p[4]["enumeration"] = "yes"
p[0] = ast.EnumDeclAST(self, p[3], p[4], p[7])
+ def p_decl__state_decl(self, p):
+ "decl : STATE_DECL '(' type pairs ')' '{' type_states '}'"
+ p[4]["enumeration"] = "yes"
+ p[4]["state_decl"] = "yes"
+ p[0] = ast.StateDeclAST(self, p[3], p[4], p[7])
+
def p_decl__object(self, p):
"decl : type ident pairs SEMI"
p[0] = ast.ObjDeclAST(self, p[1], p[2], p[3])
@@ -387,6 +394,19 @@ class SLICC(Grammar):
"type_enum : ident pairs SEMI"
p[0] = ast.TypeFieldEnumAST(self, p[1], p[2])
+ # States
+ def p_type_states__list(self, p):
+ "type_states : type_state type_states"
+ p[0] = [ p[1] ] + p[2]
+
+ def p_type_states__empty(self, p):
+ "type_states : empty"
+ p[0] = []
+
+ def p_type_state(self, p):
+ "type_state : ident ',' enumeration pairs SEMI"
+ p[0] = ast.TypeFieldStateAST(self, p[1], p[3], p[4])
+
# Type
def p_types__multiple(self, p):
"types : type ',' types"
diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py
index 1251196c9..3c5f860ea 100644
--- a/src/mem/slicc/symbols/StateMachine.py
+++ b/src/mem/slicc/symbols/StateMachine.py
@@ -347,6 +347,8 @@ static int m_num_controllers;
// Set and Reset for cache_entry variable
void set_cache_entry(${{self.EntryType.c_ident}}*& m_cache_entry_ptr, AbstractCacheEntry* m_new_cache_entry);
void unset_cache_entry(${{self.EntryType.c_ident}}*& m_cache_entry_ptr);
+// Set permissions for the cache_entry
+void set_permission(${{self.EntryType.c_ident}}*& m_cache_entry_ptr, AccessPermission perm);
''')
if self.TBEType != None:
@@ -850,6 +852,15 @@ $c_ident::unset_cache_entry(${{self.EntryType.c_ident}}*& m_cache_entry_ptr)
{
m_cache_entry_ptr = 0;
}
+
+void
+$c_ident::set_permission(${{self.EntryType.c_ident}}*& m_cache_entry_ptr,
+ AccessPermission perm)
+{
+ if (m_cache_entry_ptr != NULL) {
+ m_cache_entry_ptr->changePermission(perm);
+ }
+}
''')
if self.TBEType != None:
@@ -1090,10 +1101,12 @@ ${ident}_Controller::doTransition(${ident}_Event event,
''')
if self.TBEType != None and self.EntryType != None:
code('${ident}_setState(m_tbe_ptr, m_cache_entry_ptr, addr, next_state);')
+ code('set_permission(m_cache_entry_ptr, ${ident}_State_to_permission(next_state));')
elif self.TBEType != None:
code('${ident}_setState(m_tbe_ptr, addr, next_state);')
elif self.EntryType != None:
code('${ident}_setState(m_cache_entry_ptr, addr, next_state);')
+ code('set_permission(m_cache_entry_ptr, ${ident}_State_to_permission(next_state));')
else:
code('${ident}_setState(addr, next_state);')
diff --git a/src/mem/slicc/symbols/Type.py b/src/mem/slicc/symbols/Type.py
index e521d544f..da9ecba3a 100644
--- a/src/mem/slicc/symbols/Type.py
+++ b/src/mem/slicc/symbols/Type.py
@@ -100,6 +100,9 @@ class Type(Symbol):
self.isMachineType = (ident == "MachineType")
+ self.isStateDecl = ("state_decl" in self)
+ self.statePermPairs = []
+
self.data_members = orderdict()
# Methods
@@ -158,6 +161,9 @@ class Type(Symbol):
def methodIdAbstract(self, name, param_type_vec):
return '_'.join([name] + [ pt.abstract_ident for pt in param_type_vec ])
+ def statePermPairAdd(self, state_name, perm_name):
+ self.statePermPairs.append([state_name, perm_name])
+
def methodAdd(self, name, return_type, param_type_vec):
ident = self.methodId(name, param_type_vec)
if ident in self.methods:
@@ -446,6 +452,11 @@ ${{self.c_ident}}::print(ostream& out) const
#include <string>
#include "mem/ruby/common/Global.hh"
+''')
+ if self.isStateDecl:
+ code('#include "mem/protocol/AccessPermission.hh"')
+
+ code('''
// Class definition
/** \\enum ${{self.c_ident}}
@@ -491,6 +502,14 @@ int ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj);
for enum in self.enums.itervalues():
code('#define MACHINETYPE_${{enum.ident}} 1')
+ if self.isStateDecl:
+ code('''
+
+// Code to convert the current state to an access permission
+AccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj);
+
+''')
+
# Trailer
code('''
std::ostream& operator<<(std::ostream& out, const ${{self.c_ident}}& obj);
@@ -519,6 +538,27 @@ using namespace std;
''')
+ if self.isStateDecl:
+ code('''
+// Code to convert the current state to an access permission
+AccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj)
+{
+ switch(obj) {
+''')
+ # For each case
+ code.indent()
+ for statePerm in self.statePermPairs:
+ code(' case ${{self.c_ident}}_${{statePerm[0]}}:')
+ code(' return AccessPermission_${{statePerm[1]}};')
+ code.dedent()
+ code ('''
+ default:
+ panic("Unknown state access permission converstion for ${{self.c_ident}}");
+ }
+}
+
+''')
+
if self.isMachineType:
for enum in self.enums.itervalues():
code('#include "mem/protocol/${{enum.ident}}_Controller.hh"')