ruby: call setMRU from L1 controllers, not from sequencer
Currently the sequencer calls the function setMRU that updates the replacement policy structures with the first level caches. While functionally this is correct, the problem is that this requires calling findTagInSet() which is an expensive function. This patch removes the calls to setMRU from the sequencer. All controllers should now update the replacement policy on their own. The set and the way index for a given cache entry can be found within the AbstractCacheEntry structure. Use these indicies to update the replacement policy structures.
This commit is contained in:
parent
b815221718
commit
5060e572ca
10 changed files with 122 additions and 41 deletions
|
@ -459,21 +459,38 @@ machine(L0Cache, "MESI Directory L0 Cache")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
action(h_load_hit, "h", desc="If not prefetch, notify sequencer the load completed.") {
|
action(h_load_hit, "hd", desc="If not prefetch, notify sequencer the load completed.") {
|
||||||
assert(is_valid(cache_entry));
|
assert(is_valid(cache_entry));
|
||||||
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
|
Dcache.setMRU(cache_entry);
|
||||||
sequencer.readCallback(address, cache_entry.DataBlk);
|
sequencer.readCallback(address, cache_entry.DataBlk);
|
||||||
}
|
}
|
||||||
|
|
||||||
action(hx_load_hit, "hx", desc="If not prefetch, notify sequencer the load completed.") {
|
action(h_ifetch_hit, "hi", desc="If not prefetch, notify sequencer the ifetch completed.") {
|
||||||
assert(is_valid(cache_entry));
|
assert(is_valid(cache_entry));
|
||||||
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
|
Icache.setMRU(cache_entry);
|
||||||
|
sequencer.readCallback(address, cache_entry.DataBlk);
|
||||||
|
}
|
||||||
|
|
||||||
|
action(hx_load_hit, "hxd", desc="notify sequencer the load completed.") {
|
||||||
|
assert(is_valid(cache_entry));
|
||||||
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
|
Dcache.setMRU(cache_entry);
|
||||||
|
sequencer.readCallback(address, cache_entry.DataBlk, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
action(hx_ifetch_hit, "hxi", desc="notify sequencer the ifetch completed.") {
|
||||||
|
assert(is_valid(cache_entry));
|
||||||
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
|
Icache.setMRU(cache_entry);
|
||||||
sequencer.readCallback(address, cache_entry.DataBlk, true);
|
sequencer.readCallback(address, cache_entry.DataBlk, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
action(hh_store_hit, "\h", desc="If not prefetch, notify sequencer that store completed.") {
|
action(hh_store_hit, "\h", desc="If not prefetch, notify sequencer that store completed.") {
|
||||||
assert(is_valid(cache_entry));
|
assert(is_valid(cache_entry));
|
||||||
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
|
Dcache.setMRU(cache_entry);
|
||||||
sequencer.writeCallback(address, cache_entry.DataBlk);
|
sequencer.writeCallback(address, cache_entry.DataBlk);
|
||||||
cache_entry.Dirty := true;
|
cache_entry.Dirty := true;
|
||||||
}
|
}
|
||||||
|
@ -481,6 +498,7 @@ machine(L0Cache, "MESI Directory L0 Cache")
|
||||||
action(hhx_store_hit, "\hx", desc="If not prefetch, notify sequencer that store completed.") {
|
action(hhx_store_hit, "\hx", desc="If not prefetch, notify sequencer that store completed.") {
|
||||||
assert(is_valid(cache_entry));
|
assert(is_valid(cache_entry));
|
||||||
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
|
Dcache.setMRU(cache_entry);
|
||||||
sequencer.writeCallback(address, cache_entry.DataBlk, true);
|
sequencer.writeCallback(address, cache_entry.DataBlk, true);
|
||||||
cache_entry.Dirty := true;
|
cache_entry.Dirty := true;
|
||||||
}
|
}
|
||||||
|
@ -625,7 +643,7 @@ machine(L0Cache, "MESI Directory L0 Cache")
|
||||||
}
|
}
|
||||||
|
|
||||||
transition({S,E,M}, Ifetch) {
|
transition({S,E,M}, Ifetch) {
|
||||||
h_load_hit;
|
h_ifetch_hit;
|
||||||
uu_profileInstHit;
|
uu_profileInstHit;
|
||||||
k_popMandatoryQueue;
|
k_popMandatoryQueue;
|
||||||
}
|
}
|
||||||
|
@ -712,7 +730,7 @@ machine(L0Cache, "MESI Directory L0 Cache")
|
||||||
|
|
||||||
transition(Inst_IS, Data, S) {
|
transition(Inst_IS, Data, S) {
|
||||||
u_writeInstToCache;
|
u_writeInstToCache;
|
||||||
hx_load_hit;
|
hx_ifetch_hit;
|
||||||
s_deallocateTBE;
|
s_deallocateTBE;
|
||||||
o_popIncomingResponseQueue;
|
o_popIncomingResponseQueue;
|
||||||
kd_wakeUpDependents;
|
kd_wakeUpDependents;
|
||||||
|
@ -720,7 +738,7 @@ machine(L0Cache, "MESI Directory L0 Cache")
|
||||||
|
|
||||||
transition(Inst_IS, Data_Exclusive, E) {
|
transition(Inst_IS, Data_Exclusive, E) {
|
||||||
u_writeInstToCache;
|
u_writeInstToCache;
|
||||||
hx_load_hit;
|
hx_ifetch_hit;
|
||||||
s_deallocateTBE;
|
s_deallocateTBE;
|
||||||
o_popIncomingResponseQueue;
|
o_popIncomingResponseQueue;
|
||||||
kd_wakeUpDependents;
|
kd_wakeUpDependents;
|
||||||
|
|
|
@ -809,36 +809,47 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
|
||||||
sequencer.invalidateSC(address);
|
sequencer.invalidateSC(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
action(h_load_hit, "h",
|
action(h_load_hit, "hd",
|
||||||
desc="If not prefetch, notify sequencer the load completed.")
|
desc="Notify sequencer the load completed.")
|
||||||
{
|
{
|
||||||
assert(is_valid(cache_entry));
|
assert(is_valid(cache_entry));
|
||||||
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
|
L1Dcache.setMRU(cache_entry);
|
||||||
sequencer.readCallback(address, cache_entry.DataBlk);
|
sequencer.readCallback(address, cache_entry.DataBlk);
|
||||||
}
|
}
|
||||||
|
|
||||||
action(hx_load_hit, "hx",
|
action(h_ifetch_hit, "hi", desc="Notify sequencer the instruction fetch completed.")
|
||||||
desc="If not prefetch, notify sequencer the load completed.")
|
|
||||||
{
|
{
|
||||||
assert(is_valid(cache_entry));
|
assert(is_valid(cache_entry));
|
||||||
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
|
L1Icache.setMRU(cache_entry);
|
||||||
|
sequencer.readCallback(address, cache_entry.DataBlk);
|
||||||
|
}
|
||||||
|
|
||||||
|
action(hx_load_hit, "hx", desc="Notify sequencer the load completed.")
|
||||||
|
{
|
||||||
|
assert(is_valid(cache_entry));
|
||||||
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
|
L1Icache.setMRU(address);
|
||||||
|
L1Dcache.setMRU(address);
|
||||||
sequencer.readCallback(address, cache_entry.DataBlk, true);
|
sequencer.readCallback(address, cache_entry.DataBlk, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
action(hh_store_hit, "\h",
|
action(hh_store_hit, "\h", desc="Notify sequencer that store completed.")
|
||||||
desc="If not prefetch, notify sequencer that store completed.")
|
|
||||||
{
|
{
|
||||||
assert(is_valid(cache_entry));
|
assert(is_valid(cache_entry));
|
||||||
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
|
L1Dcache.setMRU(cache_entry);
|
||||||
sequencer.writeCallback(address, cache_entry.DataBlk);
|
sequencer.writeCallback(address, cache_entry.DataBlk);
|
||||||
cache_entry.Dirty := true;
|
cache_entry.Dirty := true;
|
||||||
}
|
}
|
||||||
|
|
||||||
action(hhx_store_hit, "\hx",
|
action(hhx_store_hit, "\hx", desc="Notify sequencer that store completed.")
|
||||||
desc="If not prefetch, notify sequencer that store completed.")
|
|
||||||
{
|
{
|
||||||
assert(is_valid(cache_entry));
|
assert(is_valid(cache_entry));
|
||||||
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
|
L1Icache.setMRU(address);
|
||||||
|
L1Dcache.setMRU(address);
|
||||||
sequencer.writeCallback(address, cache_entry.DataBlk, true);
|
sequencer.writeCallback(address, cache_entry.DataBlk, true);
|
||||||
cache_entry.Dirty := true;
|
cache_entry.Dirty := true;
|
||||||
}
|
}
|
||||||
|
@ -1080,7 +1091,7 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
|
||||||
}
|
}
|
||||||
|
|
||||||
transition({S,E,M}, Ifetch) {
|
transition({S,E,M}, Ifetch) {
|
||||||
h_load_hit;
|
h_ifetch_hit;
|
||||||
uu_profileInstHit;
|
uu_profileInstHit;
|
||||||
k_popMandatoryQueue;
|
k_popMandatoryQueue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -353,6 +353,7 @@ machine(L1Cache, "MI Example L1 Cache")
|
||||||
action(r_load_hit, "r", desc="Notify sequencer the load completed.") {
|
action(r_load_hit, "r", desc="Notify sequencer the load completed.") {
|
||||||
assert(is_valid(cache_entry));
|
assert(is_valid(cache_entry));
|
||||||
DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk);
|
DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk);
|
||||||
|
cacheMemory.setMRU(cache_entry);
|
||||||
sequencer.readCallback(address, cache_entry.DataBlk, false);
|
sequencer.readCallback(address, cache_entry.DataBlk, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,6 +361,7 @@ machine(L1Cache, "MI Example L1 Cache")
|
||||||
peek(responseNetwork_in, ResponseMsg) {
|
peek(responseNetwork_in, ResponseMsg) {
|
||||||
assert(is_valid(cache_entry));
|
assert(is_valid(cache_entry));
|
||||||
DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk);
|
DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk);
|
||||||
|
cacheMemory.setMRU(cache_entry);
|
||||||
sequencer.readCallback(address, cache_entry.DataBlk, true,
|
sequencer.readCallback(address, cache_entry.DataBlk, true,
|
||||||
machineIDToMachineType(in_msg.Sender));
|
machineIDToMachineType(in_msg.Sender));
|
||||||
}
|
}
|
||||||
|
@ -368,6 +370,7 @@ machine(L1Cache, "MI Example L1 Cache")
|
||||||
action(s_store_hit, "s", desc="Notify sequencer that store completed.") {
|
action(s_store_hit, "s", desc="Notify sequencer that store completed.") {
|
||||||
assert(is_valid(cache_entry));
|
assert(is_valid(cache_entry));
|
||||||
DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk);
|
DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk);
|
||||||
|
cacheMemory.setMRU(cache_entry);
|
||||||
sequencer.writeCallback(address, cache_entry.DataBlk, false);
|
sequencer.writeCallback(address, cache_entry.DataBlk, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,6 +378,7 @@ machine(L1Cache, "MI Example L1 Cache")
|
||||||
peek(responseNetwork_in, ResponseMsg) {
|
peek(responseNetwork_in, ResponseMsg) {
|
||||||
assert(is_valid(cache_entry));
|
assert(is_valid(cache_entry));
|
||||||
DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk);
|
DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk);
|
||||||
|
cacheMemory.setMRU(cache_entry);
|
||||||
sequencer.writeCallback(address, cache_entry.DataBlk, true,
|
sequencer.writeCallback(address, cache_entry.DataBlk, true,
|
||||||
machineIDToMachineType(in_msg.Sender));
|
machineIDToMachineType(in_msg.Sender));
|
||||||
}
|
}
|
||||||
|
|
|
@ -635,21 +635,32 @@ machine(L1Cache, "Directory protocol")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
action(h_load_hit, "h", desc="Notify sequencer the load completed.") {
|
action(h_load_hit, "hd", desc="Notify sequencer the load completed.") {
|
||||||
assert(is_valid(cache_entry));
|
assert(is_valid(cache_entry));
|
||||||
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
|
L1Dcache.setMRU(cache_entry);
|
||||||
|
sequencer.readCallback(address, cache_entry.DataBlk);
|
||||||
|
}
|
||||||
|
|
||||||
|
action(h_ifetch_hit, "hi", desc="Notify the sequencer about ifetch completion.") {
|
||||||
|
assert(is_valid(cache_entry));
|
||||||
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
|
L1Icache.setMRU(cache_entry);
|
||||||
sequencer.readCallback(address, cache_entry.DataBlk);
|
sequencer.readCallback(address, cache_entry.DataBlk);
|
||||||
}
|
}
|
||||||
|
|
||||||
action(hx_load_hit, "hx", desc="Notify sequencer the load completed.") {
|
action(hx_load_hit, "hx", desc="Notify sequencer the load completed.") {
|
||||||
assert(is_valid(cache_entry));
|
assert(is_valid(cache_entry));
|
||||||
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
|
L1Icache.setMRU(address);
|
||||||
|
L1Dcache.setMRU(address);
|
||||||
sequencer.readCallback(address, cache_entry.DataBlk, true);
|
sequencer.readCallback(address, cache_entry.DataBlk, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
action(hh_store_hit, "\h", desc="Notify sequencer that store completed.") {
|
action(hh_store_hit, "\h", desc="Notify sequencer that store completed.") {
|
||||||
assert(is_valid(cache_entry));
|
assert(is_valid(cache_entry));
|
||||||
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
|
L1Dcache.setMRU(cache_entry);
|
||||||
sequencer.writeCallback(address, cache_entry.DataBlk);
|
sequencer.writeCallback(address, cache_entry.DataBlk);
|
||||||
cache_entry.Dirty := true;
|
cache_entry.Dirty := true;
|
||||||
}
|
}
|
||||||
|
@ -657,6 +668,8 @@ machine(L1Cache, "Directory protocol")
|
||||||
action(xx_store_hit, "\xx", desc="Notify sequencer that store completed.") {
|
action(xx_store_hit, "\xx", desc="Notify sequencer that store completed.") {
|
||||||
assert(is_valid(cache_entry));
|
assert(is_valid(cache_entry));
|
||||||
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
|
L1Icache.setMRU(address);
|
||||||
|
L1Dcache.setMRU(address);
|
||||||
sequencer.writeCallback(address, cache_entry.DataBlk, true);
|
sequencer.writeCallback(address, cache_entry.DataBlk, true);
|
||||||
cache_entry.Dirty := true;
|
cache_entry.Dirty := true;
|
||||||
}
|
}
|
||||||
|
@ -964,7 +977,7 @@ machine(L1Cache, "Directory protocol")
|
||||||
}
|
}
|
||||||
|
|
||||||
transition({S, SM, O, OM, MM, MM_W, M, M_W}, Ifetch) {
|
transition({S, SM, O, OM, MM, MM_W, M, M_W}, Ifetch) {
|
||||||
h_load_hit;
|
h_ifetch_hit;
|
||||||
uu_profileInstHit;
|
uu_profileInstHit;
|
||||||
k_popMandatoryQueue;
|
k_popMandatoryQueue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1284,12 +1284,22 @@ machine(L1Cache, "Token protocol")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
action(h_load_hit, "hd", desc="Notify sequencer the load completed.") {
|
||||||
action(h_load_hit, "h", desc="Notify sequencer the load completed.") {
|
|
||||||
assert(is_valid(cache_entry));
|
assert(is_valid(cache_entry));
|
||||||
DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
|
DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
|
||||||
address, cache_entry.DataBlk);
|
address, cache_entry.DataBlk);
|
||||||
|
|
||||||
|
L1Dcache.setMRU(cache_entry);
|
||||||
|
sequencer.readCallback(address, cache_entry.DataBlk, false,
|
||||||
|
MachineType:L1Cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
action(h_ifetch_hit, "hi", desc="Notify sequencer the load completed.") {
|
||||||
|
assert(is_valid(cache_entry));
|
||||||
|
DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
|
||||||
|
address, cache_entry.DataBlk);
|
||||||
|
|
||||||
|
L1Icache.setMRU(cache_entry);
|
||||||
sequencer.readCallback(address, cache_entry.DataBlk, false,
|
sequencer.readCallback(address, cache_entry.DataBlk, false,
|
||||||
MachineType:L1Cache);
|
MachineType:L1Cache);
|
||||||
}
|
}
|
||||||
|
@ -1299,6 +1309,8 @@ machine(L1Cache, "Token protocol")
|
||||||
DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
|
DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
|
||||||
address, cache_entry.DataBlk);
|
address, cache_entry.DataBlk);
|
||||||
peek(responseNetwork_in, ResponseMsg) {
|
peek(responseNetwork_in, ResponseMsg) {
|
||||||
|
L1Icache.setMRU(address);
|
||||||
|
L1Dcache.setMRU(address);
|
||||||
sequencer.readCallback(address, cache_entry.DataBlk,
|
sequencer.readCallback(address, cache_entry.DataBlk,
|
||||||
isExternalHit(address, in_msg.Sender),
|
isExternalHit(address, in_msg.Sender),
|
||||||
machineIDToMachineType(in_msg.Sender));
|
machineIDToMachineType(in_msg.Sender));
|
||||||
|
@ -1310,6 +1322,7 @@ machine(L1Cache, "Token protocol")
|
||||||
DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
|
DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
|
||||||
address, cache_entry.DataBlk);
|
address, cache_entry.DataBlk);
|
||||||
|
|
||||||
|
L1Dcache.setMRU(cache_entry);
|
||||||
sequencer.writeCallback(address, cache_entry.DataBlk, false,
|
sequencer.writeCallback(address, cache_entry.DataBlk, false,
|
||||||
MachineType:L1Cache);
|
MachineType:L1Cache);
|
||||||
cache_entry.Dirty := true;
|
cache_entry.Dirty := true;
|
||||||
|
@ -1321,6 +1334,8 @@ machine(L1Cache, "Token protocol")
|
||||||
DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
|
DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
|
||||||
address, cache_entry.DataBlk);
|
address, cache_entry.DataBlk);
|
||||||
peek(responseNetwork_in, ResponseMsg) {
|
peek(responseNetwork_in, ResponseMsg) {
|
||||||
|
L1Icache.setMRU(address);
|
||||||
|
L1Dcache.setMRU(address);
|
||||||
sequencer.writeCallback(address, cache_entry.DataBlk,
|
sequencer.writeCallback(address, cache_entry.DataBlk,
|
||||||
isExternalHit(address, in_msg.Sender),
|
isExternalHit(address, in_msg.Sender),
|
||||||
machineIDToMachineType(in_msg.Sender));
|
machineIDToMachineType(in_msg.Sender));
|
||||||
|
@ -1702,7 +1717,7 @@ machine(L1Cache, "Token protocol")
|
||||||
}
|
}
|
||||||
|
|
||||||
transition({S, SM, S_L, SM_L}, Ifetch) {
|
transition({S, SM, S_L, SM_L}, Ifetch) {
|
||||||
h_load_hit;
|
h_ifetch_hit;
|
||||||
uu_profileInstHit;
|
uu_profileInstHit;
|
||||||
k_popMandatoryQueue;
|
k_popMandatoryQueue;
|
||||||
}
|
}
|
||||||
|
@ -1784,7 +1799,7 @@ machine(L1Cache, "Token protocol")
|
||||||
|
|
||||||
// Transitions from Owned
|
// Transitions from Owned
|
||||||
transition({O, OM}, Ifetch) {
|
transition({O, OM}, Ifetch) {
|
||||||
h_load_hit;
|
h_ifetch_hit;
|
||||||
uu_profileInstHit;
|
uu_profileInstHit;
|
||||||
k_popMandatoryQueue;
|
k_popMandatoryQueue;
|
||||||
}
|
}
|
||||||
|
@ -1874,7 +1889,7 @@ machine(L1Cache, "Token protocol")
|
||||||
|
|
||||||
// Transitions from Modified
|
// Transitions from Modified
|
||||||
transition({MM, MM_W}, Ifetch) {
|
transition({MM, MM_W}, Ifetch) {
|
||||||
h_load_hit;
|
h_ifetch_hit;
|
||||||
uu_profileInstHit;
|
uu_profileInstHit;
|
||||||
k_popMandatoryQueue;
|
k_popMandatoryQueue;
|
||||||
}
|
}
|
||||||
|
@ -1949,7 +1964,7 @@ machine(L1Cache, "Token protocol")
|
||||||
|
|
||||||
// Transitions from Dirty Exclusive
|
// Transitions from Dirty Exclusive
|
||||||
transition({M, M_W}, Ifetch) {
|
transition({M, M_W}, Ifetch) {
|
||||||
h_load_hit;
|
h_ifetch_hit;
|
||||||
uu_profileInstHit;
|
uu_profileInstHit;
|
||||||
k_popMandatoryQueue;
|
k_popMandatoryQueue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -857,9 +857,18 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
action(h_load_hit, "h", desc="Notify sequencer the load completed.") {
|
action(h_load_hit, "hd", desc="Notify sequencer the load completed.") {
|
||||||
assert(is_valid(cache_entry));
|
assert(is_valid(cache_entry));
|
||||||
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
|
L1Dcache.setMRU(cache_entry);
|
||||||
|
sequencer.readCallback(address, cache_entry.DataBlk, false,
|
||||||
|
testAndClearLocalHit(cache_entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
action(h_ifetch_hit, "hi", desc="Notify sequencer the ifetch completed.") {
|
||||||
|
assert(is_valid(cache_entry));
|
||||||
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
|
L1Icache.setMRU(cache_entry);
|
||||||
sequencer.readCallback(address, cache_entry.DataBlk, false,
|
sequencer.readCallback(address, cache_entry.DataBlk, false,
|
||||||
testAndClearLocalHit(cache_entry));
|
testAndClearLocalHit(cache_entry));
|
||||||
}
|
}
|
||||||
|
@ -869,7 +878,8 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol")
|
||||||
assert(is_valid(tbe));
|
assert(is_valid(tbe));
|
||||||
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
peek(responseToCache_in, ResponseMsg) {
|
peek(responseToCache_in, ResponseMsg) {
|
||||||
|
L1Icache.setMRU(address);
|
||||||
|
L1Dcache.setMRU(address);
|
||||||
sequencer.readCallback(address, cache_entry.DataBlk, true,
|
sequencer.readCallback(address, cache_entry.DataBlk, true,
|
||||||
machineIDToMachineType(in_msg.Sender), tbe.InitialRequestTime,
|
machineIDToMachineType(in_msg.Sender), tbe.InitialRequestTime,
|
||||||
tbe.ForwardRequestTime, tbe.FirstResponseTime);
|
tbe.ForwardRequestTime, tbe.FirstResponseTime);
|
||||||
|
@ -880,6 +890,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol")
|
||||||
assert(is_valid(cache_entry));
|
assert(is_valid(cache_entry));
|
||||||
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
peek(mandatoryQueue_in, RubyRequest) {
|
peek(mandatoryQueue_in, RubyRequest) {
|
||||||
|
L1Dcache.setMRU(cache_entry);
|
||||||
sequencer.writeCallback(address, cache_entry.DataBlk, false,
|
sequencer.writeCallback(address, cache_entry.DataBlk, false,
|
||||||
testAndClearLocalHit(cache_entry));
|
testAndClearLocalHit(cache_entry));
|
||||||
|
|
||||||
|
@ -901,7 +912,8 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol")
|
||||||
assert(is_valid(tbe));
|
assert(is_valid(tbe));
|
||||||
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
peek(responseToCache_in, ResponseMsg) {
|
peek(responseToCache_in, ResponseMsg) {
|
||||||
|
L1Icache.setMRU(address);
|
||||||
|
L1Dcache.setMRU(address);
|
||||||
sequencer.writeCallback(address, cache_entry.DataBlk, true,
|
sequencer.writeCallback(address, cache_entry.DataBlk, true,
|
||||||
machineIDToMachineType(in_msg.Sender), tbe.InitialRequestTime,
|
machineIDToMachineType(in_msg.Sender), tbe.InitialRequestTime,
|
||||||
tbe.ForwardRequestTime, tbe.FirstResponseTime);
|
tbe.ForwardRequestTime, tbe.FirstResponseTime);
|
||||||
|
@ -914,7 +926,8 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol")
|
||||||
assert(is_valid(cache_entry));
|
assert(is_valid(cache_entry));
|
||||||
assert(is_valid(tbe));
|
assert(is_valid(tbe));
|
||||||
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
|
||||||
|
L1Icache.setMRU(address);
|
||||||
|
L1Dcache.setMRU(address);
|
||||||
sequencer.writeCallback(address, cache_entry.DataBlk, true,
|
sequencer.writeCallback(address, cache_entry.DataBlk, true,
|
||||||
machineIDToMachineType(tbe.LastResponder), tbe.InitialRequestTime,
|
machineIDToMachineType(tbe.LastResponder), tbe.InitialRequestTime,
|
||||||
tbe.ForwardRequestTime, tbe.FirstResponseTime);
|
tbe.ForwardRequestTime, tbe.FirstResponseTime);
|
||||||
|
@ -1508,7 +1521,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol")
|
||||||
}
|
}
|
||||||
|
|
||||||
transition({S, SM, ISM}, Ifetch) {
|
transition({S, SM, ISM}, Ifetch) {
|
||||||
h_load_hit;
|
h_ifetch_hit;
|
||||||
uu_profileL1InstHit;
|
uu_profileL1InstHit;
|
||||||
k_popMandatoryQueue;
|
k_popMandatoryQueue;
|
||||||
}
|
}
|
||||||
|
@ -1522,7 +1535,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol")
|
||||||
}
|
}
|
||||||
|
|
||||||
transition(SR, Ifetch, S) {
|
transition(SR, Ifetch, S) {
|
||||||
h_load_hit;
|
h_ifetch_hit;
|
||||||
uu_profileL1InstMiss;
|
uu_profileL1InstMiss;
|
||||||
uu_profileL2Hit;
|
uu_profileL2Hit;
|
||||||
k_popMandatoryQueue;
|
k_popMandatoryQueue;
|
||||||
|
@ -1570,7 +1583,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol")
|
||||||
}
|
}
|
||||||
|
|
||||||
transition({O, OM, SS, MM_W, M_W}, {Ifetch}) {
|
transition({O, OM, SS, MM_W, M_W}, {Ifetch}) {
|
||||||
h_load_hit;
|
h_ifetch_hit;
|
||||||
uu_profileL1InstHit;
|
uu_profileL1InstHit;
|
||||||
k_popMandatoryQueue;
|
k_popMandatoryQueue;
|
||||||
}
|
}
|
||||||
|
@ -1584,7 +1597,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol")
|
||||||
}
|
}
|
||||||
|
|
||||||
transition(OR, Ifetch, O) {
|
transition(OR, Ifetch, O) {
|
||||||
h_load_hit;
|
h_ifetch_hit;
|
||||||
uu_profileL1InstMiss;
|
uu_profileL1InstMiss;
|
||||||
uu_profileL2Hit;
|
uu_profileL2Hit;
|
||||||
k_popMandatoryQueue;
|
k_popMandatoryQueue;
|
||||||
|
@ -1635,7 +1648,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol")
|
||||||
|
|
||||||
// Transitions from Modified
|
// Transitions from Modified
|
||||||
transition({MM, M}, {Ifetch}) {
|
transition({MM, M}, {Ifetch}) {
|
||||||
h_load_hit;
|
h_ifetch_hit;
|
||||||
uu_profileL1InstHit;
|
uu_profileL1InstHit;
|
||||||
k_popMandatoryQueue;
|
k_popMandatoryQueue;
|
||||||
}
|
}
|
||||||
|
@ -1661,7 +1674,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol")
|
||||||
}
|
}
|
||||||
|
|
||||||
transition(MMR, Ifetch, MM) {
|
transition(MMR, Ifetch, MM) {
|
||||||
h_load_hit;
|
h_ifetch_hit;
|
||||||
uu_profileL1InstMiss;
|
uu_profileL1InstMiss;
|
||||||
uu_profileL2Hit;
|
uu_profileL2Hit;
|
||||||
k_popMandatoryQueue;
|
k_popMandatoryQueue;
|
||||||
|
@ -1742,7 +1755,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol")
|
||||||
}
|
}
|
||||||
|
|
||||||
transition(MR, Ifetch, M) {
|
transition(MR, Ifetch, M) {
|
||||||
h_load_hit;
|
h_ifetch_hit;
|
||||||
uu_profileL1InstMiss;
|
uu_profileL1InstMiss;
|
||||||
uu_profileL2Hit;
|
uu_profileL2Hit;
|
||||||
k_popMandatoryQueue;
|
k_popMandatoryQueue;
|
||||||
|
|
|
@ -156,6 +156,7 @@ structure (CacheMemory, external = "yes") {
|
||||||
Cycles getTagLatency();
|
Cycles getTagLatency();
|
||||||
Cycles getDataLatency();
|
Cycles getDataLatency();
|
||||||
void setMRU(Addr);
|
void setMRU(Addr);
|
||||||
|
void setMRU(AbstractCacheEntry);
|
||||||
void recordRequestType(CacheRequestType, Addr);
|
void recordRequestType(CacheRequestType, Addr);
|
||||||
bool checkResourceAvailable(CacheResourceType, Addr);
|
bool checkResourceAvailable(CacheResourceType, Addr);
|
||||||
|
|
||||||
|
|
|
@ -343,6 +343,14 @@ CacheMemory::setMRU(Addr address)
|
||||||
m_replacementPolicy_ptr->touch(cacheSet, loc, curTick());
|
m_replacementPolicy_ptr->touch(cacheSet, loc, curTick());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CacheMemory::setMRU(const AbstractCacheEntry *e)
|
||||||
|
{
|
||||||
|
uint32_t cacheSet = e->getSetIndex();
|
||||||
|
uint32_t loc = e->getWayIndex();
|
||||||
|
m_replacementPolicy_ptr->touch(cacheSet, loc, curTick());
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CacheMemory::recordCacheContents(int cntrl, CacheRecorder* tr) const
|
CacheMemory::recordCacheContents(int cntrl, CacheRecorder* tr) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -106,6 +106,8 @@ class CacheMemory : public SimObject
|
||||||
|
|
||||||
// Set this address to most recently used
|
// Set this address to most recently used
|
||||||
void setMRU(Addr address);
|
void setMRU(Addr address);
|
||||||
|
// Set this entry to most recently used
|
||||||
|
void setMRU(const AbstractCacheEntry *e);
|
||||||
|
|
||||||
// Functions for locking and unlocking cache lines corresponding to the
|
// Functions for locking and unlocking cache lines corresponding to the
|
||||||
// provided address. These are required for supporting atomic memory
|
// provided address. These are required for supporting atomic memory
|
||||||
|
|
|
@ -496,19 +496,15 @@ Sequencer::hitCallback(SequencerRequest* srequest, DataBlock& data,
|
||||||
const Cycles forwardRequestTime,
|
const Cycles forwardRequestTime,
|
||||||
const Cycles firstResponseTime)
|
const Cycles firstResponseTime)
|
||||||
{
|
{
|
||||||
|
warn_once("Replacement policy updates recently became the responsibility "
|
||||||
|
"of SLICC state machines. Make sure to setMRU() near callbacks "
|
||||||
|
"in .sm files!");
|
||||||
|
|
||||||
PacketPtr pkt = srequest->pkt;
|
PacketPtr pkt = srequest->pkt;
|
||||||
Addr request_address(pkt->getAddr());
|
Addr request_address(pkt->getAddr());
|
||||||
Addr request_line_address = makeLineAddress(pkt->getAddr());
|
|
||||||
RubyRequestType type = srequest->m_type;
|
RubyRequestType type = srequest->m_type;
|
||||||
Cycles issued_time = srequest->issue_time;
|
Cycles issued_time = srequest->issue_time;
|
||||||
|
|
||||||
// Set this cache entry to the most recently used
|
|
||||||
if (type == RubyRequestType_IFETCH) {
|
|
||||||
m_instCache_ptr->setMRU(request_line_address);
|
|
||||||
} else {
|
|
||||||
m_dataCache_ptr->setMRU(request_line_address);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(curCycle() >= issued_time);
|
assert(curCycle() >= issued_time);
|
||||||
Cycles total_latency = curCycle() - issued_time;
|
Cycles total_latency = curCycle() - issued_time;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue