mem-ruby: Replace SLICC queueMemory calls with enqueue

Calls to queueMemoryRead and queueMemoryWrite do not consider the size
of the queue between ruby directories and DRAMCtrl which causes infinite
buffering in the queued port between the two. This adds a MessageBuffer
in between which uses enqueues in SLICC and is therefore size checked
before any SLICC transaction pushing to the buffer can occur, removing
the infinite buffering between the two.

Change-Id: Iedb9070844e4f6c8532a9c914d126105ec98d0bc
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/27427
Tested-by: Gem5 Cloud Project GCB service account <345032938727@cloudbuild.gserviceaccount.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Bradford Beckmann <brad.beckmann@amd.com>
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Reviewed-by: Matt Sinclair <mattdsinclair@gmail.com>
Maintainer: Bradford Beckmann <brad.beckmann@amd.com>
This commit is contained in:
Matt Poremba
2018-02-08 11:48:21 -08:00
committed by Matthew Poremba
parent 8b2b0f8d71
commit 53b6e21c63
25 changed files with 445 additions and 172 deletions

View File

@@ -214,10 +214,11 @@ class DirController(Directory_Controller):
self.forwardToCache = MessageBuffer(ordered = True)
self.forwardToCache.master = ruby_system.network.slave
# This is another special message buffer. It is used to send replies
# from memory back to the controller. Any messages received on the
# memory port (see self.memory above) will be directed to this
# message buffer.
# These are other special message buffers. They are used to send
# requests to memory and responses from memory back to the controller.
# Any messages sent or received on the memory port (see self.memory
# above) will be directed through these message buffers.
self.requestToMemory = MessageBuffer()
self.responseFromMemory = MessageBuffer()
class MyNetwork(SimpleNetwork):

View File

@@ -204,6 +204,7 @@ class DirController(Directory_Controller):
self.dmaResponseFromDir.master = ruby_system.network.slave
self.forwardFromDir = MessageBuffer()
self.forwardFromDir.master = ruby_system.network.slave
self.requestToMemory = MessageBuffer()
self.responseFromMemory = MessageBuffer()
class MyNetwork(SimpleNetwork):

View File

@@ -499,6 +499,7 @@ def create_system(options, full_system, system, dma_devices, bootmem,
dir_cntrl.triggerQueue = MessageBuffer(ordered = True)
dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True)
dir_cntrl.requestToMemory = MessageBuffer()
dir_cntrl.responseFromMemory = MessageBuffer()
exec("system.dir_cntrl%d = dir_cntrl" % i)

View File

@@ -453,6 +453,7 @@ def create_system(options, full_system, system, dma_devices, bootmem,
dir_cntrl.triggerQueue = MessageBuffer(ordered = True)
dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True)
dir_cntrl.requestToMemory = MessageBuffer()
dir_cntrl.responseFromMemory = MessageBuffer()
exec("ruby_system.dir_cntrl%d = dir_cntrl" % i)

View File

@@ -431,6 +431,7 @@ def create_system(options, full_system, system, dma_devices, bootmem,
dir_cntrl.triggerQueue = MessageBuffer(ordered = True)
dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True)
dir_cntrl.requestToMemory = MessageBuffer()
dir_cntrl.responseFromMemory = MessageBuffer()
exec("system.dir_cntrl%d = dir_cntrl" % i)

View File

@@ -711,6 +711,7 @@ def create_system(options, full_system, system, dma_devices, bootmem,
dir_cntrl.triggerQueue = MessageBuffer(ordered = True)
dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True)
dir_cntrl.requestToMemory = MessageBuffer()
dir_cntrl.responseFromMemory = MessageBuffer()
exec("system.dir_cntrl%d = dir_cntrl" % i)

View File

@@ -185,6 +185,7 @@ def create_system(options, full_system, system, dma_ports, bootmem,
dir_cntrl.responseToDir.slave = ruby_system.network.master
dir_cntrl.responseFromDir = MessageBuffer()
dir_cntrl.responseFromDir.master = ruby_system.network.slave
dir_cntrl.requestToMemory = MessageBuffer()
dir_cntrl.responseFromMemory = MessageBuffer()

View File

@@ -142,6 +142,7 @@ def create_system(options, full_system, system, dma_ports, bootmem,
dir_cntrl.dmaResponseFromDir.master = ruby_system.network.slave
dir_cntrl.forwardFromDir = MessageBuffer()
dir_cntrl.forwardFromDir.master = ruby_system.network.slave
dir_cntrl.requestToMemory = MessageBuffer()
dir_cntrl.responseFromMemory = MessageBuffer()

View File

@@ -209,6 +209,7 @@ def create_system(options, full_system, system, dma_ports, bootmem,
dir_cntrl.responseFromDir.master = ruby_system.network.slave
dir_cntrl.forwardFromDir = MessageBuffer()
dir_cntrl.forwardFromDir.master = ruby_system.network.slave
dir_cntrl.requestToMemory = MessageBuffer()
dir_cntrl.responseFromMemory = MessageBuffer()

View File

@@ -214,6 +214,7 @@ def create_system(options, full_system, system, dma_ports, bootmem,
dir_cntrl.persistentFromDir.master = ruby_system.network.slave
dir_cntrl.dmaResponseFromDir = MessageBuffer(ordered = True)
dir_cntrl.dmaResponseFromDir.master = ruby_system.network.slave
dir_cntrl.requestToMemory = MessageBuffer()
dir_cntrl.responseFromMemory = MessageBuffer()

View File

@@ -206,6 +206,7 @@ def create_system(options, full_system, system, dma_ports, bootmem,
dir_cntrl.requestToDir.slave = ruby_system.network.master
dir_cntrl.dmaRequestToDir = MessageBuffer(ordered = True)
dir_cntrl.dmaRequestToDir.slave = ruby_system.network.master
dir_cntrl.requestToMemory = MessageBuffer()
dir_cntrl.responseFromMemory = MessageBuffer()

View File

@@ -74,6 +74,9 @@ machine(MachineType:Directory, "Directory protocol")
MessageBuffer *responseFromCache, network="From", virtual_network="2",
vnet_type="response";
// Special buffer for memory requests. Kind of like the mandatory queue
MessageBuffer *requestToMemory;
// Special buffer for memory responses. Kind of like the mandatory queue
MessageBuffer *responseFromMemory;
@@ -209,6 +212,7 @@ machine(MachineType:Directory, "Directory protocol")
out_port(forward_out, RequestMsg, forwardToCache);
out_port(response_out, ResponseMsg, responseToCache);
out_port(memQueue_out, MemoryMsg, requestToMemory);
in_port(memQueue_in, MemoryMsg, responseFromMemory) {
if (memQueue_in.isReady(clockEdge())) {
@@ -279,11 +283,16 @@ machine(MachineType:Directory, "Directory protocol")
action(sendMemRead, "r", desc="Send a memory read request") {
peek(request_in, RequestMsg) {
// Special function from AbstractController that will send a new
// packet out of the "Ruby" black box to the memory side. At some
// point the response will be on the memory queue.
// Like enqeue, this takes a latency for the request.
queueMemoryRead(in_msg.Requestor, address, toMemLatency);
// Send request through special memory request queue. At some
// point the response will be on the memory response queue.
// Like enqueue, this takes a latency for the request.
enqueue(memQueue_out, MemoryMsg, toMemLatency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_READ;
out_msg.Sender := in_msg.Requestor;
out_msg.MessageSize := MessageSizeType:Request_Control;
out_msg.Len := 0;
}
}
}
@@ -291,8 +300,14 @@ machine(MachineType:Directory, "Directory protocol")
peek(request_in, RequestMsg) {
DPRINTF(RubySlicc, "Writing memory for %#x\n", address);
DPRINTF(RubySlicc, "Writing %s\n", in_msg.DataBlk);
queueMemoryWrite(in_msg.Requestor, address, toMemLatency,
in_msg.DataBlk);
enqueue(memQueue_out, MemoryMsg, toMemLatency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := in_msg.Requestor;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := in_msg.DataBlk;
out_msg.Len := 0;
}
}
}
@@ -300,8 +315,14 @@ machine(MachineType:Directory, "Directory protocol")
peek(response_in, ResponseMsg) {
DPRINTF(RubySlicc, "Writing memory for %#x\n", address);
DPRINTF(RubySlicc, "Writing %s\n", in_msg.DataBlk);
queueMemoryWrite(in_msg.Sender, address, toMemLatency,
in_msg.DataBlk);
enqueue(memQueue_out, MemoryMsg, toMemLatency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := in_msg.Sender;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := in_msg.DataBlk;
out_msg.Len := 0;
}
}
}

View File

@@ -38,6 +38,7 @@ machine(MachineType:Directory, "MESI Two Level directory protocol")
MessageBuffer * responseFromDir, network="To", virtual_network="1",
vnet_type="response";
MessageBuffer * requestToMemory;
MessageBuffer * responseFromMemory;
{
// STATES
@@ -189,6 +190,7 @@ machine(MachineType:Directory, "MESI Two Level directory protocol")
// ** OUT_PORTS **
out_port(responseNetwork_out, ResponseMsg, responseFromDir);
out_port(memQueue_out, MemoryMsg, requestToMemory);
// ** IN_PORTS **
@@ -306,21 +308,39 @@ machine(MachineType:Directory, "MESI Two Level directory protocol")
action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
peek(requestNetwork_in, RequestMsg) {
queueMemoryRead(in_msg.Requestor, address, to_mem_ctrl_latency);
enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_READ;
out_msg.Sender := in_msg.Requestor;
out_msg.MessageSize := MessageSizeType:Request_Control;
out_msg.Len := 0;
}
}
}
action(qw_queueMemoryWBRequest, "qw", desc="Queue off-chip writeback request") {
peek(responseNetwork_in, ResponseMsg) {
queueMemoryWrite(in_msg.Sender, address, to_mem_ctrl_latency,
in_msg.DataBlk);
enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := in_msg.Sender;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := in_msg.DataBlk;
out_msg.Len := 0;
}
}
}
//added by SS for dma
action(qf_queueMemoryFetchRequestDMA, "qfd", desc="Queue off-chip fetch request") {
peek(requestNetwork_in, RequestMsg) {
queueMemoryRead(in_msg.Requestor, address, to_mem_ctrl_latency);
enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_READ;
out_msg.Sender := in_msg.Requestor;
out_msg.MessageSize := MessageSizeType:Request_Control;
out_msg.Len := 0;
}
}
}
@@ -344,8 +364,14 @@ machine(MachineType:Directory, "MESI Two Level directory protocol")
action(qw_queueMemoryWBRequest_partial, "qwp",
desc="Queue off-chip writeback request") {
peek(requestNetwork_in, RequestMsg) {
queueMemoryWritePartial(machineID, address, to_mem_ctrl_latency,
in_msg.DataBlk, in_msg.Len);
enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := machineID;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := in_msg.DataBlk;
out_msg.Len := in_msg.Len;
}
}
}
@@ -407,8 +433,14 @@ machine(MachineType:Directory, "MESI Two Level directory protocol")
action(qw_queueMemoryWBRequest_partialTBE, "qwt",
desc="Queue off-chip writeback request") {
peek(responseNetwork_in, ResponseMsg) {
queueMemoryWritePartial(in_msg.Sender, tbe.PhysicalAddress,
to_mem_ctrl_latency, tbe.DataBlk, tbe.Len);
enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) {
out_msg.addr := tbe.PhysicalAddress;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := in_msg.Sender;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := tbe.DataBlk;
out_msg.Len := tbe.Len;
}
}
}

View File

@@ -43,6 +43,8 @@ machine(MachineType:Directory, "Directory protocol")
vnet_type="request";
MessageBuffer * dmaRequestToDir, network="From", virtual_network="0",
vnet_type="request";
MessageBuffer * requestToMemory;
MessageBuffer * responseFromMemory;
{
// STATES
@@ -204,6 +206,7 @@ machine(MachineType:Directory, "Directory protocol")
out_port(responseNetwork_out, ResponseMsg, responseFromDir);
out_port(requestQueue_out, ResponseMsg, requestToDir); // For recycling requests
out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir);
out_port(memQueue_out, MemoryMsg, requestToMemory);
// ** IN_PORTS **
in_port(dmaRequestQueue_in, DMARequestMsg, dmaRequestToDir) {
@@ -445,36 +448,64 @@ machine(MachineType:Directory, "Directory protocol")
action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
peek(requestQueue_in, RequestMsg) {
queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_READ;
out_msg.Sender := in_msg.Requestor;
out_msg.MessageSize := MessageSizeType:Request_Control;
out_msg.Len := 0;
}
}
}
action(qf_queueMemoryFetchRequestDMA, "qfd", desc="Queue off-chip fetch request") {
peek(dmaRequestQueue_in, DMARequestMsg) {
queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_READ;
out_msg.Sender := in_msg.Requestor;
out_msg.MessageSize := MessageSizeType:Request_Control;
out_msg.Len := 0;
}
}
}
action(qw_queueMemoryWBRequest_partial, "qwp", desc="Queue off-chip writeback request") {
peek(dmaRequestQueue_in, DMARequestMsg) {
queueMemoryWritePartial(in_msg.Requestor, address,
to_memory_controller_latency, in_msg.DataBlk,
in_msg.Len);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := in_msg.Requestor;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := in_msg.DataBlk;
out_msg.Len := in_msg.Len;
}
}
}
action(qw_queueMemoryWBRequest_partialTBE, "qwt", desc="Queue off-chip writeback request") {
peek(requestQueue_in, RequestMsg) {
queueMemoryWritePartial(in_msg.Requestor, address,
to_memory_controller_latency, tbe.DataBlk,
tbe.Len);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := in_msg.Requestor;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := tbe.DataBlk;
out_msg.Len := tbe.Len;
}
}
}
action(l_queueMemoryWBRequest, "lq", desc="Write PUTX data to memory") {
peek(requestQueue_in, RequestMsg) {
queueMemoryWrite(in_msg.Requestor, address, to_memory_controller_latency,
in_msg.DataBlk);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := in_msg.Requestor;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := in_msg.DataBlk;
out_msg.Len := 0;
}
}
}

View File

@@ -59,6 +59,8 @@ machine(MachineType:Directory, "AMD_Base-like protocol")
MessageBuffer * triggerQueue;
MessageBuffer * L3triggerQueue;
MessageBuffer * requestToMemory;
MessageBuffer * responseFromMemory;
{
// STATES
@@ -319,6 +321,8 @@ machine(MachineType:Directory, "AMD_Base-like protocol")
out_port(triggerQueue_out, TriggerMsg, triggerQueue);
out_port(L3TriggerQueue_out, TriggerMsg, L3triggerQueue);
out_port(memQueue_out, MemoryMsg, requestToMemory);
// ** IN_PORTS **
// Trigger Queue
@@ -841,7 +845,12 @@ machine(MachineType:Directory, "AMD_Base-like protocol")
DPRINTF(RubySlicc, "L3 data is %s\n", entry.DataBlk);
L3CacheMemory.deallocate(address);
} else {
queueMemoryRead(machineID, address, to_memory_controller_latency);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_READ;
out_msg.Sender := machineID;
out_msg.MessageSize := MessageSizeType:Request_Control;
}
}
}
}
@@ -862,7 +871,12 @@ machine(MachineType:Directory, "AMD_Base-like protocol")
DPRINTF(RubySlicc, "L3 data is %s\n", entry.DataBlk);
L3CacheMemory.deallocate(address);
} else {
queueMemoryRead(machineID, address, to_memory_controller_latency);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_READ;
out_msg.Sender := machineID;
out_msg.MessageSize := MessageSizeType:Request_Control;
}
}
}
}
@@ -1254,8 +1268,13 @@ machine(MachineType:Directory, "AMD_Base-like protocol")
Addr victim := L3CacheMemory.cacheProbe(address);
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
L3CacheMemory.lookup(victim));
queueMemoryWrite(machineID, victim, to_memory_controller_latency,
victim_entry.DataBlk);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := victim;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := machineID;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := victim_entry.DataBlk;
}
L3CacheMemory.deallocate(victim);
}
assert(L3CacheMemory.cacheAvail(address));
@@ -1279,8 +1298,13 @@ machine(MachineType:Directory, "AMD_Base-like protocol")
Addr victim := L3CacheMemory.cacheProbe(address);
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
L3CacheMemory.lookup(victim));
queueMemoryWrite(machineID, victim, to_memory_controller_latency,
victim_entry.DataBlk);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := victim;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := machineID;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := victim_entry.DataBlk;
}
L3CacheMemory.deallocate(victim);
}
assert(L3CacheMemory.cacheAvail(address));
@@ -1304,8 +1328,13 @@ machine(MachineType:Directory, "AMD_Base-like protocol")
Addr victim := L3CacheMemory.cacheProbe(address);
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
L3CacheMemory.lookup(victim));
queueMemoryWrite(machineID, victim, to_memory_controller_latency,
victim_entry.DataBlk);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := victim;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := machineID;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := victim_entry.DataBlk;
}
L3CacheMemory.deallocate(victim);
}
assert(L3CacheMemory.cacheAvail(address));
@@ -1330,8 +1359,13 @@ machine(MachineType:Directory, "AMD_Base-like protocol")
Addr victim := L3CacheMemory.cacheProbe(address);
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
L3CacheMemory.lookup(victim));
queueMemoryWrite(machineID, victim, to_memory_controller_latency,
victim_entry.DataBlk);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := victim;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := machineID;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := victim_entry.DataBlk;
}
L3CacheMemory.deallocate(victim);
}
assert(L3CacheMemory.cacheAvail(address));

View File

@@ -52,6 +52,8 @@ machine(MachineType:Directory, "AMD Baseline protocol")
MessageBuffer * triggerQueue;
MessageBuffer * L3triggerQueue;
MessageBuffer * requestToMemory;
MessageBuffer * responseFromMemory;
{
// STATES
@@ -270,6 +272,8 @@ machine(MachineType:Directory, "AMD Baseline protocol")
out_port(triggerQueue_out, TriggerMsg, triggerQueue);
out_port(L3TriggerQueue_out, TriggerMsg, L3triggerQueue);
out_port(memQueue_out, MemoryMsg, requestToMemory);
// ** IN_PORTS **
// Trigger Queue
@@ -516,8 +520,13 @@ machine(MachineType:Directory, "AMD Baseline protocol")
action(l_queueMemWBReq, "lq", desc="Write WB data to memory") {
peek(responseNetwork_in, ResponseMsg) {
queueMemoryWrite(machineID, address, to_memory_controller_latency,
in_msg.DataBlk);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := machineID;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := in_msg.DataBlk;
}
}
}
@@ -538,7 +547,12 @@ machine(MachineType:Directory, "AMD Baseline protocol")
tbe.MemData := true;
L3CacheMemory.deallocate(address);
} else {
queueMemoryRead(machineID, address, to_memory_controller_latency);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_READ;
out_msg.Sender := machineID;
out_msg.MessageSize := MessageSizeType:Request_Control;
}
}
}
}
@@ -795,8 +809,13 @@ machine(MachineType:Directory, "AMD Baseline protocol")
Addr victim := L3CacheMemory.cacheProbe(address);
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
L3CacheMemory.lookup(victim));
queueMemoryWrite(machineID, victim, to_memory_controller_latency,
victim_entry.DataBlk);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := victim;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := machineID;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := victim_entry.DataBlk;
}
L3CacheMemory.deallocate(victim);
}
assert(L3CacheMemory.cacheAvail(address));
@@ -821,8 +840,13 @@ machine(MachineType:Directory, "AMD Baseline protocol")
Addr victim := L3CacheMemory.cacheProbe(address);
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
L3CacheMemory.lookup(victim));
queueMemoryWrite(machineID, victim, to_memory_controller_latency,
victim_entry.DataBlk);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := victim;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := machineID;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := victim_entry.DataBlk;
}
L3CacheMemory.deallocate(victim);
}
assert(L3CacheMemory.cacheAvail(address));

View File

@@ -64,6 +64,8 @@ machine(MachineType:Directory, "AMD Baseline protocol")
MessageBuffer * triggerQueue, ordered="true";
MessageBuffer * L3triggerQueue, ordered="true";
MessageBuffer * requestToMemory;
MessageBuffer * responseFromMemory;
{
// STATES
@@ -349,6 +351,8 @@ machine(MachineType:Directory, "AMD Baseline protocol")
out_port(triggerQueue_out, TriggerMsg, triggerQueue);
out_port(L3TriggerQueue_out, TriggerMsg, L3triggerQueue);
out_port(memQueue_out, MemoryMsg, requestToMemory);
// ** IN_PORTS **
// Trigger Queue
@@ -605,8 +609,13 @@ machine(MachineType:Directory, "AMD Baseline protocol")
action(l_queueMemWBReq, "lq", desc="Write WB data to memory") {
peek(responseNetwork_in, ResponseMsg) {
queueMemoryWrite(machineID, address, to_memory_controller_latency,
in_msg.DataBlk);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := machineID;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := in_msg.DataBlk;
}
}
}
@@ -625,7 +634,12 @@ machine(MachineType:Directory, "AMD Baseline protocol")
tbe.MemData := true;
L3CacheMemory.deallocate(address);
} else {
queueMemoryRead(machineID, address, to_memory_controller_latency);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_READ;
out_msg.Sender := machineID;
out_msg.MessageSize := MessageSizeType:Request_Control;
}
}
}
}
@@ -942,8 +956,13 @@ machine(MachineType:Directory, "AMD Baseline protocol")
Addr victim := L3CacheMemory.cacheProbe(address);
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
L3CacheMemory.lookup(victim));
queueMemoryWrite(machineID, victim, to_memory_controller_latency,
victim_entry.DataBlk);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := victim;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := machineID;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := victim_entry.DataBlk;
}
L3CacheMemory.deallocate(victim);
}
assert(L3CacheMemory.cacheAvail(address));
@@ -968,8 +987,13 @@ machine(MachineType:Directory, "AMD Baseline protocol")
Addr victim := L3CacheMemory.cacheProbe(address);
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
L3CacheMemory.lookup(victim));
queueMemoryWrite(machineID, victim, to_memory_controller_latency,
victim_entry.DataBlk);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := victim;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := machineID;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := victim_entry.DataBlk;
}
L3CacheMemory.deallocate(victim);
}
assert(L3CacheMemory.cacheAvail(address));

View File

@@ -54,6 +54,7 @@ machine(MachineType:Directory, "Directory protocol")
MessageBuffer * responseFromDir, network="To", virtual_network="2",
vnet_type="response"; // Dir -> mod-L2 bank
MessageBuffer * requestToMemory;
MessageBuffer * responseFromMemory;
{
// STATES
@@ -237,6 +238,7 @@ machine(MachineType:Directory, "Directory protocol")
// ** OUT_PORTS **
out_port(forwardNetwork_out, RequestMsg, forwardFromDir);
out_port(responseNetwork_out, ResponseMsg, responseFromDir);
out_port(memQueue_out, MemoryMsg, requestToMemory);
// ** IN_PORTS **
@@ -479,18 +481,36 @@ machine(MachineType:Directory, "Directory protocol")
action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
peek(requestQueue_in, RequestMsg) {
queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_READ;
out_msg.Sender := in_msg.Requestor;
out_msg.MessageSize := MessageSizeType:Request_Control;
out_msg.Len := 0;
}
}
}
action(qw_queueMemoryWBFromCacheRequest, "qw", desc="Queue off-chip writeback request") {
peek(requestQueue_in, RequestMsg) {
if (is_valid(tbe)) {
queueMemoryWrite(tbe.Requestor, address, to_memory_controller_latency,
in_msg.DataBlk);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := tbe.Requestor;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := in_msg.DataBlk;
out_msg.Len := 0;
}
} else {
queueMemoryWrite(in_msg.Requestor, address, to_memory_controller_latency,
in_msg.DataBlk);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := in_msg.Requestor;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := in_msg.DataBlk;
out_msg.Len := 0;
}
}
}
}
@@ -501,15 +521,27 @@ machine(MachineType:Directory, "Directory protocol")
DataBlock DataBlk := in_msg.DataBlk;
DataBlk.copyPartial(tbe.DataBlk, getOffset(tbe.PhysicalAddress),
tbe.Len);
queueMemoryWrite(tbe.Requestor, address, to_memory_controller_latency,
DataBlk);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := tbe.Requestor;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := DataBlk;
out_msg.Len := 0;
}
}
}
action(qw_queueMemoryWBFromDMARequest, "/qw", desc="Queue off-chip writeback request") {
peek(requestQueue_in, RequestMsg) {
queueMemoryWrite(in_msg.Requestor, address, to_memory_controller_latency,
in_msg.DataBlk);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := in_msg.Requestor;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := in_msg.DataBlk;
out_msg.Len := 0;
}
}
}

View File

@@ -61,6 +61,7 @@ machine(MachineType:Directory, "Token protocol")
MessageBuffer * dmaRequestToDir, network="From", virtual_network="0",
vnet_type="request";
MessageBuffer * requestToMemory;
MessageBuffer * responseFromMemory;
{
// STATES
@@ -276,6 +277,7 @@ machine(MachineType:Directory, "Token protocol")
out_port(persistentNetwork_out, PersistentMsg, persistentFromDir);
out_port(requestNetwork_out, RequestMsg, requestFromDir);
out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir);
out_port(memQueue_out, MemoryMsg, requestToMemory);
// ** IN_PORTS **
// off-chip memory request/response is done
@@ -656,39 +658,73 @@ machine(MachineType:Directory, "Token protocol")
action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
peek(requestNetwork_in, RequestMsg) {
queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_READ;
out_msg.Sender := in_msg.Requestor;
out_msg.MessageSize := MessageSizeType:Request_Control;
out_msg.Len := 0;
}
}
}
action(qp_queueMemoryForPersistent, "qp", desc="Queue off-chip fetch request") {
queueMemoryRead(persistentTable.findSmallest(address), address,
to_memory_controller_latency);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_READ;
out_msg.Sender := persistentTable.findSmallest(address);
out_msg.MessageSize := MessageSizeType:Request_Control;
out_msg.Len := 0;
}
}
action(fd_memoryDma, "fd", desc="Queue off-chip fetch request") {
peek(dmaRequestQueue_in, DMARequestMsg) {
queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_READ;
out_msg.Sender := in_msg.Requestor;
out_msg.MessageSize := MessageSizeType:Request_Control;
out_msg.Len := 0;
}
}
}
action(lq_queueMemoryWbRequest, "lq", desc="Write data to memory") {
peek(responseNetwork_in, ResponseMsg) {
queueMemoryWrite(in_msg.Sender, address, to_memory_controller_latency,
in_msg.DataBlk);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := in_msg.Sender;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := in_msg.DataBlk;
out_msg.Len := 0;
}
}
}
action(ld_queueMemoryDmaWriteFromTbe, "ld", desc="Write DMA data to memory") {
queueMemoryWritePartial(tbe.DmaRequestor, address,
to_memory_controller_latency, tbe.DataBlk,
tbe.Len);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := tbe.DmaRequestor;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := tbe.DataBlk;
out_msg.Len := tbe.Len;
}
}
action(lr_queueMemoryDmaReadWriteback, "lr",
desc="Write DMA data from read to memory") {
peek(responseNetwork_in, ResponseMsg) {
queueMemoryWrite(machineID, address, to_memory_controller_latency,
in_msg.DataBlk);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := machineID;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := in_msg.DataBlk;
out_msg.Len := 0;
}
}
}

View File

@@ -63,6 +63,7 @@ machine(MachineType:Directory, "AMD Hammer-like protocol")
vnet_type="request";
MessageBuffer * triggerQueue;
MessageBuffer * requestToMemory;
MessageBuffer * responseFromMemory;
{
// STATES
@@ -304,12 +305,13 @@ machine(MachineType:Directory, "AMD Hammer-like protocol")
// ** OUT_PORTS **
out_port(requestQueue_out, ResponseMsg, requestToDir); // For recycling requests
out_port(forwardNetwork_out, RequestMsg, forwardFromDir);
out_port(memQueue_out, MemoryMsg, requestToMemory);
out_port(responseNetwork_out, ResponseMsg, responseFromDir);
out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir);
out_port(triggerQueue_out, TriggerMsg, triggerQueue);
// ** IN_PORTS **
// Trigger Queue
in_port(triggerQueue_in, TriggerMsg, triggerQueue, rank=5) {
if (triggerQueue_in.isReady(clockEdge())) {
@@ -844,13 +846,25 @@ machine(MachineType:Directory, "AMD Hammer-like protocol")
action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
peek(requestQueue_in, RequestMsg) {
queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_READ;
out_msg.Sender := in_msg.Requestor;
out_msg.MessageSize := MessageSizeType:Request_Control;
out_msg.Len := 0;
}
}
}
action(qd_queueMemoryRequestFromDmaRead, "qd", desc="Queue off-chip fetch request") {
peek(dmaRequestQueue_in, DMARequestMsg) {
queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_READ;
out_msg.Sender := in_msg.Requestor;
out_msg.MessageSize := MessageSizeType:Request_Control;
out_msg.Len := 0;
}
}
}
@@ -1204,21 +1218,38 @@ machine(MachineType:Directory, "AMD Hammer-like protocol")
action(l_queueMemoryWBRequest, "lq", desc="Write PUTX data to memory") {
peek(unblockNetwork_in, ResponseMsg) {
queueMemoryWrite(in_msg.Sender, address, to_memory_controller_latency,
in_msg.DataBlk);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := in_msg.Sender;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := in_msg.DataBlk;
out_msg.Len := 0;
}
}
}
action(ld_queueMemoryDmaWrite, "ld", desc="Write DMA data to memory") {
assert(is_valid(tbe));
queueMemoryWritePartial(tbe.DmaRequestor, tbe.PhysicalAddress,
to_memory_controller_latency, tbe.DmaDataBlk,
tbe.Len);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := tbe.PhysicalAddress;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := tbe.DmaRequestor;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := tbe.DmaDataBlk;
out_msg.Len := tbe.Len;
}
}
action(ly_queueMemoryWriteFromTBE, "ly", desc="Write data to memory from TBE") {
queueMemoryWrite(machineID, address, to_memory_controller_latency,
tbe.DataBlk);
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := tbe.DmaRequestor;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := tbe.DataBlk;
out_msg.Len := 0;
}
}
action(ll_checkIncomingWriteback, "\l", desc="Check PUTX/PUTO response message") {

View File

@@ -32,15 +32,6 @@ MachineID machineID;
NodeID clusterID;
Cycles recycle_latency;
// Functions implemented in the AbstractController class for
// making timing access to the memory maintained by the
// memory controllers.
void queueMemoryRead(MachineID id, Addr addr, Cycles latency);
void queueMemoryWrite(MachineID id, Addr addr, Cycles latency,
DataBlock block);
void queueMemoryWritePartial(MachineID id, Addr addr, Cycles latency,
DataBlock block, int size);
// Functions implemented in the AbstractController class for
// making functional access to the memory maintained by the
// memory controllers.

View File

@@ -57,6 +57,7 @@ structure(MemoryMsg, desc="...", interface="Message") {
MachineID OriginalRequestorMachId, desc="What component originally requested";
DataBlock DataBlk, desc="Data to writeback";
MessageSizeType MessageSize, desc="size category of the message";
int Len, desc="size of the memory/dma request";
// Not all fields used by all protocols:
PrefetchBit Prefetch, desc="Is this a prefetch request";
bool ReadX, desc="Exclusive";

View File

@@ -76,6 +76,10 @@ AbstractController::init()
m_delayVCHistogram.push_back(new Stats::Histogram());
m_delayVCHistogram[i]->init(10);
}
if (getMemReqQueue()) {
getMemReqQueue()->setConsumer(this);
}
}
void
@@ -202,6 +206,61 @@ AbstractController::wakeUpAllBuffers()
}
}
bool
AbstractController::serviceMemoryQueue()
{
auto mem_queue = getMemReqQueue();
assert(mem_queue);
if (!mem_queue->isReady(clockEdge())) {
return false;
}
const MemoryMsg *mem_msg = (const MemoryMsg*)mem_queue->peek();
unsigned int req_size = RubySystem::getBlockSizeBytes();
if (mem_msg->m_Len > 0) {
req_size = mem_msg->m_Len;
}
RequestPtr req
= std::make_shared<Request>(mem_msg->m_addr, req_size, 0, m_masterId);
PacketPtr pkt;
if (mem_msg->getType() == MemoryRequestType_MEMORY_WB) {
pkt = Packet::createWrite(req);
pkt->allocate();
pkt->setData(mem_msg->m_DataBlk.getData(getOffset(mem_msg->m_addr),
req_size));
} else if (mem_msg->getType() == MemoryRequestType_MEMORY_READ) {
pkt = Packet::createRead(req);
uint8_t *newData = new uint8_t[req_size];
pkt->dataDynamic(newData);
} else {
panic("Unknown memory request type (%s) for addr %p",
MemoryRequestType_to_string(mem_msg->getType()),
mem_msg->m_addr);
}
SenderState *s = new SenderState(mem_msg->m_Sender);
pkt->pushSenderState(s);
if (RubySystem::getWarmupEnabled()) {
// Use functional rather than timing accesses during warmup
mem_queue->dequeue(clockEdge());
memoryPort.sendFunctional(pkt);
// Since the queue was popped the controller may be able
// to make more progress. Make sure it wakes up
scheduleEvent(Cycles(1));
recvTimingResp(pkt);
} else {
mem_queue->dequeue(clockEdge());
memoryPort.schedTimingReq(pkt, clockEdge());
// Since the queue was popped the controller may be able
// to make more progress. Make sure it wakes up
scheduleEvent(Cycles(1));
}
return true;
}
void
AbstractController::blockOnQueue(Addr addr, MessageBuffer* port)
{
@@ -236,73 +295,6 @@ AbstractController::getPort(const std::string &if_name, PortID idx)
return memoryPort;
}
void
AbstractController::queueMemoryRead(const MachineID &id, Addr addr,
Cycles latency)
{
RequestPtr req = std::make_shared<Request>(
addr, RubySystem::getBlockSizeBytes(), 0, m_masterId);
PacketPtr pkt = Packet::createRead(req);
uint8_t *newData = new uint8_t[RubySystem::getBlockSizeBytes()];
pkt->dataDynamic(newData);
SenderState *s = new SenderState(id);
pkt->pushSenderState(s);
// Use functional rather than timing accesses during warmup
if (RubySystem::getWarmupEnabled()) {
memoryPort.sendFunctional(pkt);
recvTimingResp(pkt);
return;
}
memoryPort.schedTimingReq(pkt, clockEdge(latency));
}
void
AbstractController::queueMemoryWrite(const MachineID &id, Addr addr,
Cycles latency, const DataBlock &block)
{
RequestPtr req = std::make_shared<Request>(
addr, RubySystem::getBlockSizeBytes(), 0, m_masterId);
PacketPtr pkt = Packet::createWrite(req);
pkt->allocate();
pkt->setData(block.getData(0, RubySystem::getBlockSizeBytes()));
SenderState *s = new SenderState(id);
pkt->pushSenderState(s);
// Use functional rather than timing accesses during warmup
if (RubySystem::getWarmupEnabled()) {
memoryPort.sendFunctional(pkt);
recvTimingResp(pkt);
return;
}
// Create a block and copy data from the block.
memoryPort.schedTimingReq(pkt, clockEdge(latency));
}
void
AbstractController::queueMemoryWritePartial(const MachineID &id, Addr addr,
Cycles latency,
const DataBlock &block, int size)
{
RequestPtr req = std::make_shared<Request>(addr, size, 0, m_masterId);
PacketPtr pkt = Packet::createWrite(req);
pkt->allocate();
pkt->setData(block.getData(getOffset(addr), size));
SenderState *s = new SenderState(id);
pkt->pushSenderState(s);
// Create a block and copy data from the block.
memoryPort.schedTimingReq(pkt, clockEdge(latency));
}
void
AbstractController::functionalMemoryRead(PacketPtr pkt)
{
@@ -327,7 +319,7 @@ AbstractController::functionalMemoryWrite(PacketPtr pkt)
void
AbstractController::recvTimingResp(PacketPtr pkt)
{
assert(getMemoryQueue());
assert(getMemRespQueue());
assert(pkt->isResponse());
std::shared_ptr<MemoryMsg> msg = std::make_shared<MemoryMsg>(clockEdge());
@@ -352,7 +344,7 @@ AbstractController::recvTimingResp(PacketPtr pkt)
panic("Incorrect packet type received from memory controller!");
}
getMemoryQueue()->enqueue(msg, clockEdge(), cyclesToTicks(Cycles(1)));
getMemRespQueue()->enqueue(msg, clockEdge(), cyclesToTicks(Cycles(1)));
delete pkt;
}

View File

@@ -90,7 +90,8 @@ class AbstractController : public ClockedObject, public Consumer
bool isBlocked(Addr);
virtual MessageBuffer* getMandatoryQueue() const = 0;
virtual MessageBuffer* getMemoryQueue() const = 0;
virtual MessageBuffer* getMemReqQueue() const = 0;
virtual MessageBuffer* getMemRespQueue() const = 0;
virtual AccessPermission getAccessPermission(const Addr &addr) = 0;
virtual void print(std::ostream & out) const = 0;
@@ -136,11 +137,6 @@ class AbstractController : public ClockedObject, public Consumer
Port &getPort(const std::string &if_name,
PortID idx=InvalidPortID);
void queueMemoryRead(const MachineID &id, Addr addr, Cycles latency);
void queueMemoryWrite(const MachineID &id, Addr addr, Cycles latency,
const DataBlock &block);
void queueMemoryWritePartial(const MachineID &id, Addr addr, Cycles latency,
const DataBlock &block, int size);
void recvTimingResp(PacketPtr pkt);
Tick recvAtomic(PacketPtr pkt);
@@ -178,6 +174,7 @@ class AbstractController : public ClockedObject, public Consumer
void wakeUpBuffers(Addr addr);
void wakeUpAllBuffers(Addr addr);
void wakeUpAllBuffers();
bool serviceMemoryQueue();
protected:
const NodeID m_version;

View File

@@ -299,7 +299,8 @@ class $c_ident : public AbstractController
void init();
MessageBuffer *getMandatoryQueue() const;
MessageBuffer *getMemoryQueue() const;
MessageBuffer *getMemReqQueue() const;
MessageBuffer *getMemRespQueue() const;
void initNetQueues();
void print(std::ostream& out) const;
@@ -672,6 +673,11 @@ $c_ident::init()
if port.code.find("mandatoryQueue_ptr") >= 0:
mq_ident = "m_mandatoryQueue_ptr"
memoutq_ident = "NULL"
for param in self.config_parameters:
if param.ident.find("requestToMemory") >= 0:
memoutq_ident = "m_requestToMemory_ptr"
memq_ident = "NULL"
for port in self.in_ports:
if port.code.find("responseFromMemory_ptr") >= 0:
@@ -854,7 +860,13 @@ $c_ident::getMandatoryQueue() const
}
MessageBuffer*
$c_ident::getMemoryQueue() const
$c_ident::getMemReqQueue() const
{
return $memoutq_ident;
}
MessageBuffer*
$c_ident::getMemRespQueue() const
{
return $memq_ident;
}
@@ -1085,6 +1097,10 @@ using namespace std;
void
${ident}_Controller::wakeup()
{
if (getMemReqQueue() && getMemReqQueue()->isReady(clockEdge())) {
serviceMemoryQueue();
}
int counter = 0;
while (true) {
unsigned char rejected[${{len(msg_bufs)}}];