ruby: automate permission setting
This patch integrates permissions with cache and memory states, and then automates the setting of permissions within the generated code. No longer does one need to manually set the permissions within the setState funciton. This patch will faciliate easier functional access support by always correctly setting permissions for both cache and memory states. --HG-- rename : src/mem/slicc/ast/EnumDeclAST.py => src/mem/slicc/ast/StateDeclAST.py rename : src/mem/slicc/ast/TypeFieldEnumAST.py => src/mem/slicc/ast/TypeFieldStateAST.py
This commit is contained in:
parent
7842e95519
commit
12a05c23b7
30 changed files with 514 additions and 380 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
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, 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";
|
||||
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
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
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, 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";
|
||||
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, 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";
|
||||
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, 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";
|
||||
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, 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";
|
||||
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;
|
||||
|
|
|
@ -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";
|
||||
I, AccessPermission:Invalid, desc="Invalid";
|
||||
S, AccessPermission:Read_Only, desc="Shared";
|
||||
O, AccessPermission:Read_Only, desc="Owner";
|
||||
M, AccessPermission:Read_Write, 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";
|
||||
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, 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";
|
||||
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, 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";
|
||||
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
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
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, 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";
|
||||
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, "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";
|
||||
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
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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&
|
||||
|
|
79
src/mem/slicc/ast/StateDeclAST.py
Normal file
79
src/mem/slicc/ast/StateDeclAST.py
Normal file
|
@ -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)
|
|
@ -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.")
|
||||
|
|
61
src/mem/slicc/ast/TypeFieldStateAST.py
Normal file
61
src/mem/slicc/ast/TypeFieldStateAST.py
Normal file
|
@ -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)
|
||||
|
||||
|
|
@ -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 *
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);')
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
@ -517,6 +536,27 @@ std::ostream& operator<<(std::ostream& out, const ${{self.c_ident}}& obj);
|
|||
|
||||
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:
|
||||
|
|
Loading…
Reference in a new issue