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:
Brad Beckmann 2011-02-23 16:41:59 -08:00
parent 7842e95519
commit 12a05c23b7
30 changed files with 514 additions and 380 deletions

View file

@ -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);
}
}
}

View file

@ -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);
}
}
}

View file

@ -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

View file

@ -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") {

View file

@ -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);
}
}
}

View file

@ -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

View file

@ -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") {

View file

@ -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);
}
}
}

View file

@ -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;

View file

@ -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

View file

@ -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") {

View file

@ -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);
}
}
}

View file

@ -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);
}
}
}

View file

@ -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";
}

View file

@ -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") {

View file

@ -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);
}
}
}

View file

@ -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

View file

@ -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") {

View file

@ -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);

View file

@ -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;

View file

@ -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
};

View file

@ -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;
}

View file

@ -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&

View 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)

View file

@ -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.")

View 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)

View file

@ -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 *

View file

@ -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"

View file

@ -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);')

View file

@ -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: