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:
committed by
Matthew Poremba
parent
8b2b0f8d71
commit
53b6e21c63
@@ -214,10 +214,11 @@ class DirController(Directory_Controller):
|
|||||||
self.forwardToCache = MessageBuffer(ordered = True)
|
self.forwardToCache = MessageBuffer(ordered = True)
|
||||||
self.forwardToCache.master = ruby_system.network.slave
|
self.forwardToCache.master = ruby_system.network.slave
|
||||||
|
|
||||||
# This is another special message buffer. It is used to send replies
|
# These are other special message buffers. They are used to send
|
||||||
# from memory back to the controller. Any messages received on the
|
# requests to memory and responses from memory back to the controller.
|
||||||
# memory port (see self.memory above) will be directed to this
|
# Any messages sent or received on the memory port (see self.memory
|
||||||
# message buffer.
|
# above) will be directed through these message buffers.
|
||||||
|
self.requestToMemory = MessageBuffer()
|
||||||
self.responseFromMemory = MessageBuffer()
|
self.responseFromMemory = MessageBuffer()
|
||||||
|
|
||||||
class MyNetwork(SimpleNetwork):
|
class MyNetwork(SimpleNetwork):
|
||||||
|
|||||||
@@ -204,6 +204,7 @@ class DirController(Directory_Controller):
|
|||||||
self.dmaResponseFromDir.master = ruby_system.network.slave
|
self.dmaResponseFromDir.master = ruby_system.network.slave
|
||||||
self.forwardFromDir = MessageBuffer()
|
self.forwardFromDir = MessageBuffer()
|
||||||
self.forwardFromDir.master = ruby_system.network.slave
|
self.forwardFromDir.master = ruby_system.network.slave
|
||||||
|
self.requestToMemory = MessageBuffer()
|
||||||
self.responseFromMemory = MessageBuffer()
|
self.responseFromMemory = MessageBuffer()
|
||||||
|
|
||||||
class MyNetwork(SimpleNetwork):
|
class MyNetwork(SimpleNetwork):
|
||||||
|
|||||||
@@ -499,6 +499,7 @@ def create_system(options, full_system, system, dma_devices, bootmem,
|
|||||||
|
|
||||||
dir_cntrl.triggerQueue = MessageBuffer(ordered = True)
|
dir_cntrl.triggerQueue = MessageBuffer(ordered = True)
|
||||||
dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True)
|
dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True)
|
||||||
|
dir_cntrl.requestToMemory = MessageBuffer()
|
||||||
dir_cntrl.responseFromMemory = MessageBuffer()
|
dir_cntrl.responseFromMemory = MessageBuffer()
|
||||||
|
|
||||||
exec("system.dir_cntrl%d = dir_cntrl" % i)
|
exec("system.dir_cntrl%d = dir_cntrl" % i)
|
||||||
|
|||||||
@@ -453,6 +453,7 @@ def create_system(options, full_system, system, dma_devices, bootmem,
|
|||||||
|
|
||||||
dir_cntrl.triggerQueue = MessageBuffer(ordered = True)
|
dir_cntrl.triggerQueue = MessageBuffer(ordered = True)
|
||||||
dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True)
|
dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True)
|
||||||
|
dir_cntrl.requestToMemory = MessageBuffer()
|
||||||
dir_cntrl.responseFromMemory = MessageBuffer()
|
dir_cntrl.responseFromMemory = MessageBuffer()
|
||||||
|
|
||||||
exec("ruby_system.dir_cntrl%d = dir_cntrl" % i)
|
exec("ruby_system.dir_cntrl%d = dir_cntrl" % i)
|
||||||
|
|||||||
@@ -431,6 +431,7 @@ def create_system(options, full_system, system, dma_devices, bootmem,
|
|||||||
|
|
||||||
dir_cntrl.triggerQueue = MessageBuffer(ordered = True)
|
dir_cntrl.triggerQueue = MessageBuffer(ordered = True)
|
||||||
dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True)
|
dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True)
|
||||||
|
dir_cntrl.requestToMemory = MessageBuffer()
|
||||||
dir_cntrl.responseFromMemory = MessageBuffer()
|
dir_cntrl.responseFromMemory = MessageBuffer()
|
||||||
|
|
||||||
exec("system.dir_cntrl%d = dir_cntrl" % i)
|
exec("system.dir_cntrl%d = dir_cntrl" % i)
|
||||||
|
|||||||
@@ -711,6 +711,7 @@ def create_system(options, full_system, system, dma_devices, bootmem,
|
|||||||
|
|
||||||
dir_cntrl.triggerQueue = MessageBuffer(ordered = True)
|
dir_cntrl.triggerQueue = MessageBuffer(ordered = True)
|
||||||
dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True)
|
dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True)
|
||||||
|
dir_cntrl.requestToMemory = MessageBuffer()
|
||||||
dir_cntrl.responseFromMemory = MessageBuffer()
|
dir_cntrl.responseFromMemory = MessageBuffer()
|
||||||
|
|
||||||
exec("system.dir_cntrl%d = dir_cntrl" % i)
|
exec("system.dir_cntrl%d = dir_cntrl" % i)
|
||||||
|
|||||||
@@ -185,6 +185,7 @@ def create_system(options, full_system, system, dma_ports, bootmem,
|
|||||||
dir_cntrl.responseToDir.slave = ruby_system.network.master
|
dir_cntrl.responseToDir.slave = ruby_system.network.master
|
||||||
dir_cntrl.responseFromDir = MessageBuffer()
|
dir_cntrl.responseFromDir = MessageBuffer()
|
||||||
dir_cntrl.responseFromDir.master = ruby_system.network.slave
|
dir_cntrl.responseFromDir.master = ruby_system.network.slave
|
||||||
|
dir_cntrl.requestToMemory = MessageBuffer()
|
||||||
dir_cntrl.responseFromMemory = MessageBuffer()
|
dir_cntrl.responseFromMemory = MessageBuffer()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ def create_system(options, full_system, system, dma_ports, bootmem,
|
|||||||
dir_cntrl.dmaResponseFromDir.master = ruby_system.network.slave
|
dir_cntrl.dmaResponseFromDir.master = ruby_system.network.slave
|
||||||
dir_cntrl.forwardFromDir = MessageBuffer()
|
dir_cntrl.forwardFromDir = MessageBuffer()
|
||||||
dir_cntrl.forwardFromDir.master = ruby_system.network.slave
|
dir_cntrl.forwardFromDir.master = ruby_system.network.slave
|
||||||
|
dir_cntrl.requestToMemory = MessageBuffer()
|
||||||
dir_cntrl.responseFromMemory = MessageBuffer()
|
dir_cntrl.responseFromMemory = MessageBuffer()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -209,6 +209,7 @@ def create_system(options, full_system, system, dma_ports, bootmem,
|
|||||||
dir_cntrl.responseFromDir.master = ruby_system.network.slave
|
dir_cntrl.responseFromDir.master = ruby_system.network.slave
|
||||||
dir_cntrl.forwardFromDir = MessageBuffer()
|
dir_cntrl.forwardFromDir = MessageBuffer()
|
||||||
dir_cntrl.forwardFromDir.master = ruby_system.network.slave
|
dir_cntrl.forwardFromDir.master = ruby_system.network.slave
|
||||||
|
dir_cntrl.requestToMemory = MessageBuffer()
|
||||||
dir_cntrl.responseFromMemory = MessageBuffer()
|
dir_cntrl.responseFromMemory = MessageBuffer()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -214,6 +214,7 @@ def create_system(options, full_system, system, dma_ports, bootmem,
|
|||||||
dir_cntrl.persistentFromDir.master = ruby_system.network.slave
|
dir_cntrl.persistentFromDir.master = ruby_system.network.slave
|
||||||
dir_cntrl.dmaResponseFromDir = MessageBuffer(ordered = True)
|
dir_cntrl.dmaResponseFromDir = MessageBuffer(ordered = True)
|
||||||
dir_cntrl.dmaResponseFromDir.master = ruby_system.network.slave
|
dir_cntrl.dmaResponseFromDir.master = ruby_system.network.slave
|
||||||
|
dir_cntrl.requestToMemory = MessageBuffer()
|
||||||
dir_cntrl.responseFromMemory = MessageBuffer()
|
dir_cntrl.responseFromMemory = MessageBuffer()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -206,6 +206,7 @@ def create_system(options, full_system, system, dma_ports, bootmem,
|
|||||||
dir_cntrl.requestToDir.slave = ruby_system.network.master
|
dir_cntrl.requestToDir.slave = ruby_system.network.master
|
||||||
dir_cntrl.dmaRequestToDir = MessageBuffer(ordered = True)
|
dir_cntrl.dmaRequestToDir = MessageBuffer(ordered = True)
|
||||||
dir_cntrl.dmaRequestToDir.slave = ruby_system.network.master
|
dir_cntrl.dmaRequestToDir.slave = ruby_system.network.master
|
||||||
|
dir_cntrl.requestToMemory = MessageBuffer()
|
||||||
dir_cntrl.responseFromMemory = MessageBuffer()
|
dir_cntrl.responseFromMemory = MessageBuffer()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -74,6 +74,9 @@ machine(MachineType:Directory, "Directory protocol")
|
|||||||
MessageBuffer *responseFromCache, network="From", virtual_network="2",
|
MessageBuffer *responseFromCache, network="From", virtual_network="2",
|
||||||
vnet_type="response";
|
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
|
// Special buffer for memory responses. Kind of like the mandatory queue
|
||||||
MessageBuffer *responseFromMemory;
|
MessageBuffer *responseFromMemory;
|
||||||
|
|
||||||
@@ -209,6 +212,7 @@ machine(MachineType:Directory, "Directory protocol")
|
|||||||
|
|
||||||
out_port(forward_out, RequestMsg, forwardToCache);
|
out_port(forward_out, RequestMsg, forwardToCache);
|
||||||
out_port(response_out, ResponseMsg, responseToCache);
|
out_port(response_out, ResponseMsg, responseToCache);
|
||||||
|
out_port(memQueue_out, MemoryMsg, requestToMemory);
|
||||||
|
|
||||||
in_port(memQueue_in, MemoryMsg, responseFromMemory) {
|
in_port(memQueue_in, MemoryMsg, responseFromMemory) {
|
||||||
if (memQueue_in.isReady(clockEdge())) {
|
if (memQueue_in.isReady(clockEdge())) {
|
||||||
@@ -279,11 +283,16 @@ machine(MachineType:Directory, "Directory protocol")
|
|||||||
|
|
||||||
action(sendMemRead, "r", desc="Send a memory read request") {
|
action(sendMemRead, "r", desc="Send a memory read request") {
|
||||||
peek(request_in, RequestMsg) {
|
peek(request_in, RequestMsg) {
|
||||||
// Special function from AbstractController that will send a new
|
// Send request through special memory request queue. At some
|
||||||
// packet out of the "Ruby" black box to the memory side. At some
|
// point the response will be on the memory response queue.
|
||||||
// point the response will be on the memory queue.
|
// Like enqueue, this takes a latency for the request.
|
||||||
// Like enqeue, this takes a latency for the request.
|
enqueue(memQueue_out, MemoryMsg, toMemLatency) {
|
||||||
queueMemoryRead(in_msg.Requestor, address, 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) {
|
peek(request_in, RequestMsg) {
|
||||||
DPRINTF(RubySlicc, "Writing memory for %#x\n", address);
|
DPRINTF(RubySlicc, "Writing memory for %#x\n", address);
|
||||||
DPRINTF(RubySlicc, "Writing %s\n", in_msg.DataBlk);
|
DPRINTF(RubySlicc, "Writing %s\n", in_msg.DataBlk);
|
||||||
queueMemoryWrite(in_msg.Requestor, address, toMemLatency,
|
enqueue(memQueue_out, MemoryMsg, toMemLatency) {
|
||||||
in_msg.DataBlk);
|
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) {
|
peek(response_in, ResponseMsg) {
|
||||||
DPRINTF(RubySlicc, "Writing memory for %#x\n", address);
|
DPRINTF(RubySlicc, "Writing memory for %#x\n", address);
|
||||||
DPRINTF(RubySlicc, "Writing %s\n", in_msg.DataBlk);
|
DPRINTF(RubySlicc, "Writing %s\n", in_msg.DataBlk);
|
||||||
queueMemoryWrite(in_msg.Sender, address, toMemLatency,
|
enqueue(memQueue_out, MemoryMsg, toMemLatency) {
|
||||||
in_msg.DataBlk);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ machine(MachineType:Directory, "MESI Two Level directory protocol")
|
|||||||
MessageBuffer * responseFromDir, network="To", virtual_network="1",
|
MessageBuffer * responseFromDir, network="To", virtual_network="1",
|
||||||
vnet_type="response";
|
vnet_type="response";
|
||||||
|
|
||||||
|
MessageBuffer * requestToMemory;
|
||||||
MessageBuffer * responseFromMemory;
|
MessageBuffer * responseFromMemory;
|
||||||
{
|
{
|
||||||
// STATES
|
// STATES
|
||||||
@@ -189,6 +190,7 @@ machine(MachineType:Directory, "MESI Two Level directory protocol")
|
|||||||
|
|
||||||
// ** OUT_PORTS **
|
// ** OUT_PORTS **
|
||||||
out_port(responseNetwork_out, ResponseMsg, responseFromDir);
|
out_port(responseNetwork_out, ResponseMsg, responseFromDir);
|
||||||
|
out_port(memQueue_out, MemoryMsg, requestToMemory);
|
||||||
|
|
||||||
// ** IN_PORTS **
|
// ** IN_PORTS **
|
||||||
|
|
||||||
@@ -306,21 +308,39 @@ machine(MachineType:Directory, "MESI Two Level directory protocol")
|
|||||||
|
|
||||||
action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
|
action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
|
||||||
peek(requestNetwork_in, RequestMsg) {
|
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") {
|
action(qw_queueMemoryWBRequest, "qw", desc="Queue off-chip writeback request") {
|
||||||
peek(responseNetwork_in, ResponseMsg) {
|
peek(responseNetwork_in, ResponseMsg) {
|
||||||
queueMemoryWrite(in_msg.Sender, address, to_mem_ctrl_latency,
|
enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) {
|
||||||
in_msg.DataBlk);
|
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
|
//added by SS for dma
|
||||||
action(qf_queueMemoryFetchRequestDMA, "qfd", desc="Queue off-chip fetch request") {
|
action(qf_queueMemoryFetchRequestDMA, "qfd", desc="Queue off-chip fetch request") {
|
||||||
peek(requestNetwork_in, RequestMsg) {
|
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",
|
action(qw_queueMemoryWBRequest_partial, "qwp",
|
||||||
desc="Queue off-chip writeback request") {
|
desc="Queue off-chip writeback request") {
|
||||||
peek(requestNetwork_in, RequestMsg) {
|
peek(requestNetwork_in, RequestMsg) {
|
||||||
queueMemoryWritePartial(machineID, address, to_mem_ctrl_latency,
|
enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) {
|
||||||
in_msg.DataBlk, in_msg.Len);
|
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",
|
action(qw_queueMemoryWBRequest_partialTBE, "qwt",
|
||||||
desc="Queue off-chip writeback request") {
|
desc="Queue off-chip writeback request") {
|
||||||
peek(responseNetwork_in, ResponseMsg) {
|
peek(responseNetwork_in, ResponseMsg) {
|
||||||
queueMemoryWritePartial(in_msg.Sender, tbe.PhysicalAddress,
|
enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) {
|
||||||
to_mem_ctrl_latency, tbe.DataBlk, tbe.Len);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ machine(MachineType:Directory, "Directory protocol")
|
|||||||
vnet_type="request";
|
vnet_type="request";
|
||||||
MessageBuffer * dmaRequestToDir, network="From", virtual_network="0",
|
MessageBuffer * dmaRequestToDir, network="From", virtual_network="0",
|
||||||
vnet_type="request";
|
vnet_type="request";
|
||||||
|
|
||||||
|
MessageBuffer * requestToMemory;
|
||||||
MessageBuffer * responseFromMemory;
|
MessageBuffer * responseFromMemory;
|
||||||
{
|
{
|
||||||
// STATES
|
// STATES
|
||||||
@@ -204,6 +206,7 @@ machine(MachineType:Directory, "Directory protocol")
|
|||||||
out_port(responseNetwork_out, ResponseMsg, responseFromDir);
|
out_port(responseNetwork_out, ResponseMsg, responseFromDir);
|
||||||
out_port(requestQueue_out, ResponseMsg, requestToDir); // For recycling requests
|
out_port(requestQueue_out, ResponseMsg, requestToDir); // For recycling requests
|
||||||
out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir);
|
out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir);
|
||||||
|
out_port(memQueue_out, MemoryMsg, requestToMemory);
|
||||||
|
|
||||||
// ** IN_PORTS **
|
// ** IN_PORTS **
|
||||||
in_port(dmaRequestQueue_in, DMARequestMsg, dmaRequestToDir) {
|
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") {
|
action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
|
||||||
peek(requestQueue_in, RequestMsg) {
|
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") {
|
action(qf_queueMemoryFetchRequestDMA, "qfd", desc="Queue off-chip fetch request") {
|
||||||
peek(dmaRequestQueue_in, DMARequestMsg) {
|
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") {
|
action(qw_queueMemoryWBRequest_partial, "qwp", desc="Queue off-chip writeback request") {
|
||||||
peek(dmaRequestQueue_in, DMARequestMsg) {
|
peek(dmaRequestQueue_in, DMARequestMsg) {
|
||||||
queueMemoryWritePartial(in_msg.Requestor, address,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
to_memory_controller_latency, in_msg.DataBlk,
|
out_msg.addr := address;
|
||||||
in_msg.Len);
|
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") {
|
action(qw_queueMemoryWBRequest_partialTBE, "qwt", desc="Queue off-chip writeback request") {
|
||||||
peek(requestQueue_in, RequestMsg) {
|
peek(requestQueue_in, RequestMsg) {
|
||||||
queueMemoryWritePartial(in_msg.Requestor, address,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
to_memory_controller_latency, tbe.DataBlk,
|
out_msg.addr := address;
|
||||||
tbe.Len);
|
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") {
|
action(l_queueMemoryWBRequest, "lq", desc="Write PUTX data to memory") {
|
||||||
peek(requestQueue_in, RequestMsg) {
|
peek(requestQueue_in, RequestMsg) {
|
||||||
queueMemoryWrite(in_msg.Requestor, address, to_memory_controller_latency,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
in_msg.DataBlk);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ machine(MachineType:Directory, "AMD_Base-like protocol")
|
|||||||
|
|
||||||
MessageBuffer * triggerQueue;
|
MessageBuffer * triggerQueue;
|
||||||
MessageBuffer * L3triggerQueue;
|
MessageBuffer * L3triggerQueue;
|
||||||
|
|
||||||
|
MessageBuffer * requestToMemory;
|
||||||
MessageBuffer * responseFromMemory;
|
MessageBuffer * responseFromMemory;
|
||||||
{
|
{
|
||||||
// STATES
|
// STATES
|
||||||
@@ -319,6 +321,8 @@ machine(MachineType:Directory, "AMD_Base-like protocol")
|
|||||||
out_port(triggerQueue_out, TriggerMsg, triggerQueue);
|
out_port(triggerQueue_out, TriggerMsg, triggerQueue);
|
||||||
out_port(L3TriggerQueue_out, TriggerMsg, L3triggerQueue);
|
out_port(L3TriggerQueue_out, TriggerMsg, L3triggerQueue);
|
||||||
|
|
||||||
|
out_port(memQueue_out, MemoryMsg, requestToMemory);
|
||||||
|
|
||||||
// ** IN_PORTS **
|
// ** IN_PORTS **
|
||||||
|
|
||||||
// Trigger Queue
|
// Trigger Queue
|
||||||
@@ -841,7 +845,12 @@ machine(MachineType:Directory, "AMD_Base-like protocol")
|
|||||||
DPRINTF(RubySlicc, "L3 data is %s\n", entry.DataBlk);
|
DPRINTF(RubySlicc, "L3 data is %s\n", entry.DataBlk);
|
||||||
L3CacheMemory.deallocate(address);
|
L3CacheMemory.deallocate(address);
|
||||||
} else {
|
} 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);
|
DPRINTF(RubySlicc, "L3 data is %s\n", entry.DataBlk);
|
||||||
L3CacheMemory.deallocate(address);
|
L3CacheMemory.deallocate(address);
|
||||||
} else {
|
} 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);
|
Addr victim := L3CacheMemory.cacheProbe(address);
|
||||||
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
|
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
|
||||||
L3CacheMemory.lookup(victim));
|
L3CacheMemory.lookup(victim));
|
||||||
queueMemoryWrite(machineID, victim, to_memory_controller_latency,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
victim_entry.DataBlk);
|
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);
|
L3CacheMemory.deallocate(victim);
|
||||||
}
|
}
|
||||||
assert(L3CacheMemory.cacheAvail(address));
|
assert(L3CacheMemory.cacheAvail(address));
|
||||||
@@ -1279,8 +1298,13 @@ machine(MachineType:Directory, "AMD_Base-like protocol")
|
|||||||
Addr victim := L3CacheMemory.cacheProbe(address);
|
Addr victim := L3CacheMemory.cacheProbe(address);
|
||||||
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
|
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
|
||||||
L3CacheMemory.lookup(victim));
|
L3CacheMemory.lookup(victim));
|
||||||
queueMemoryWrite(machineID, victim, to_memory_controller_latency,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
victim_entry.DataBlk);
|
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);
|
L3CacheMemory.deallocate(victim);
|
||||||
}
|
}
|
||||||
assert(L3CacheMemory.cacheAvail(address));
|
assert(L3CacheMemory.cacheAvail(address));
|
||||||
@@ -1304,8 +1328,13 @@ machine(MachineType:Directory, "AMD_Base-like protocol")
|
|||||||
Addr victim := L3CacheMemory.cacheProbe(address);
|
Addr victim := L3CacheMemory.cacheProbe(address);
|
||||||
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
|
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
|
||||||
L3CacheMemory.lookup(victim));
|
L3CacheMemory.lookup(victim));
|
||||||
queueMemoryWrite(machineID, victim, to_memory_controller_latency,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
victim_entry.DataBlk);
|
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);
|
L3CacheMemory.deallocate(victim);
|
||||||
}
|
}
|
||||||
assert(L3CacheMemory.cacheAvail(address));
|
assert(L3CacheMemory.cacheAvail(address));
|
||||||
@@ -1330,8 +1359,13 @@ machine(MachineType:Directory, "AMD_Base-like protocol")
|
|||||||
Addr victim := L3CacheMemory.cacheProbe(address);
|
Addr victim := L3CacheMemory.cacheProbe(address);
|
||||||
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
|
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
|
||||||
L3CacheMemory.lookup(victim));
|
L3CacheMemory.lookup(victim));
|
||||||
queueMemoryWrite(machineID, victim, to_memory_controller_latency,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
victim_entry.DataBlk);
|
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);
|
L3CacheMemory.deallocate(victim);
|
||||||
}
|
}
|
||||||
assert(L3CacheMemory.cacheAvail(address));
|
assert(L3CacheMemory.cacheAvail(address));
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ machine(MachineType:Directory, "AMD Baseline protocol")
|
|||||||
|
|
||||||
MessageBuffer * triggerQueue;
|
MessageBuffer * triggerQueue;
|
||||||
MessageBuffer * L3triggerQueue;
|
MessageBuffer * L3triggerQueue;
|
||||||
|
|
||||||
|
MessageBuffer * requestToMemory;
|
||||||
MessageBuffer * responseFromMemory;
|
MessageBuffer * responseFromMemory;
|
||||||
{
|
{
|
||||||
// STATES
|
// STATES
|
||||||
@@ -270,6 +272,8 @@ machine(MachineType:Directory, "AMD Baseline protocol")
|
|||||||
out_port(triggerQueue_out, TriggerMsg, triggerQueue);
|
out_port(triggerQueue_out, TriggerMsg, triggerQueue);
|
||||||
out_port(L3TriggerQueue_out, TriggerMsg, L3triggerQueue);
|
out_port(L3TriggerQueue_out, TriggerMsg, L3triggerQueue);
|
||||||
|
|
||||||
|
out_port(memQueue_out, MemoryMsg, requestToMemory);
|
||||||
|
|
||||||
// ** IN_PORTS **
|
// ** IN_PORTS **
|
||||||
|
|
||||||
// Trigger Queue
|
// Trigger Queue
|
||||||
@@ -516,8 +520,13 @@ machine(MachineType:Directory, "AMD Baseline protocol")
|
|||||||
|
|
||||||
action(l_queueMemWBReq, "lq", desc="Write WB data to memory") {
|
action(l_queueMemWBReq, "lq", desc="Write WB data to memory") {
|
||||||
peek(responseNetwork_in, ResponseMsg) {
|
peek(responseNetwork_in, ResponseMsg) {
|
||||||
queueMemoryWrite(machineID, address, to_memory_controller_latency,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
in_msg.DataBlk);
|
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;
|
tbe.MemData := true;
|
||||||
L3CacheMemory.deallocate(address);
|
L3CacheMemory.deallocate(address);
|
||||||
} else {
|
} 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);
|
Addr victim := L3CacheMemory.cacheProbe(address);
|
||||||
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
|
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
|
||||||
L3CacheMemory.lookup(victim));
|
L3CacheMemory.lookup(victim));
|
||||||
queueMemoryWrite(machineID, victim, to_memory_controller_latency,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
victim_entry.DataBlk);
|
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);
|
L3CacheMemory.deallocate(victim);
|
||||||
}
|
}
|
||||||
assert(L3CacheMemory.cacheAvail(address));
|
assert(L3CacheMemory.cacheAvail(address));
|
||||||
@@ -821,8 +840,13 @@ machine(MachineType:Directory, "AMD Baseline protocol")
|
|||||||
Addr victim := L3CacheMemory.cacheProbe(address);
|
Addr victim := L3CacheMemory.cacheProbe(address);
|
||||||
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
|
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
|
||||||
L3CacheMemory.lookup(victim));
|
L3CacheMemory.lookup(victim));
|
||||||
queueMemoryWrite(machineID, victim, to_memory_controller_latency,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
victim_entry.DataBlk);
|
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);
|
L3CacheMemory.deallocate(victim);
|
||||||
}
|
}
|
||||||
assert(L3CacheMemory.cacheAvail(address));
|
assert(L3CacheMemory.cacheAvail(address));
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ machine(MachineType:Directory, "AMD Baseline protocol")
|
|||||||
|
|
||||||
MessageBuffer * triggerQueue, ordered="true";
|
MessageBuffer * triggerQueue, ordered="true";
|
||||||
MessageBuffer * L3triggerQueue, ordered="true";
|
MessageBuffer * L3triggerQueue, ordered="true";
|
||||||
|
|
||||||
|
MessageBuffer * requestToMemory;
|
||||||
MessageBuffer * responseFromMemory;
|
MessageBuffer * responseFromMemory;
|
||||||
{
|
{
|
||||||
// STATES
|
// STATES
|
||||||
@@ -349,6 +351,8 @@ machine(MachineType:Directory, "AMD Baseline protocol")
|
|||||||
out_port(triggerQueue_out, TriggerMsg, triggerQueue);
|
out_port(triggerQueue_out, TriggerMsg, triggerQueue);
|
||||||
out_port(L3TriggerQueue_out, TriggerMsg, L3triggerQueue);
|
out_port(L3TriggerQueue_out, TriggerMsg, L3triggerQueue);
|
||||||
|
|
||||||
|
out_port(memQueue_out, MemoryMsg, requestToMemory);
|
||||||
|
|
||||||
// ** IN_PORTS **
|
// ** IN_PORTS **
|
||||||
|
|
||||||
// Trigger Queue
|
// Trigger Queue
|
||||||
@@ -605,8 +609,13 @@ machine(MachineType:Directory, "AMD Baseline protocol")
|
|||||||
|
|
||||||
action(l_queueMemWBReq, "lq", desc="Write WB data to memory") {
|
action(l_queueMemWBReq, "lq", desc="Write WB data to memory") {
|
||||||
peek(responseNetwork_in, ResponseMsg) {
|
peek(responseNetwork_in, ResponseMsg) {
|
||||||
queueMemoryWrite(machineID, address, to_memory_controller_latency,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
in_msg.DataBlk);
|
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;
|
tbe.MemData := true;
|
||||||
L3CacheMemory.deallocate(address);
|
L3CacheMemory.deallocate(address);
|
||||||
} else {
|
} 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);
|
Addr victim := L3CacheMemory.cacheProbe(address);
|
||||||
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
|
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
|
||||||
L3CacheMemory.lookup(victim));
|
L3CacheMemory.lookup(victim));
|
||||||
queueMemoryWrite(machineID, victim, to_memory_controller_latency,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
victim_entry.DataBlk);
|
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);
|
L3CacheMemory.deallocate(victim);
|
||||||
}
|
}
|
||||||
assert(L3CacheMemory.cacheAvail(address));
|
assert(L3CacheMemory.cacheAvail(address));
|
||||||
@@ -968,8 +987,13 @@ machine(MachineType:Directory, "AMD Baseline protocol")
|
|||||||
Addr victim := L3CacheMemory.cacheProbe(address);
|
Addr victim := L3CacheMemory.cacheProbe(address);
|
||||||
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
|
CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
|
||||||
L3CacheMemory.lookup(victim));
|
L3CacheMemory.lookup(victim));
|
||||||
queueMemoryWrite(machineID, victim, to_memory_controller_latency,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
victim_entry.DataBlk);
|
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);
|
L3CacheMemory.deallocate(victim);
|
||||||
}
|
}
|
||||||
assert(L3CacheMemory.cacheAvail(address));
|
assert(L3CacheMemory.cacheAvail(address));
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ machine(MachineType:Directory, "Directory protocol")
|
|||||||
MessageBuffer * responseFromDir, network="To", virtual_network="2",
|
MessageBuffer * responseFromDir, network="To", virtual_network="2",
|
||||||
vnet_type="response"; // Dir -> mod-L2 bank
|
vnet_type="response"; // Dir -> mod-L2 bank
|
||||||
|
|
||||||
|
MessageBuffer * requestToMemory;
|
||||||
MessageBuffer * responseFromMemory;
|
MessageBuffer * responseFromMemory;
|
||||||
{
|
{
|
||||||
// STATES
|
// STATES
|
||||||
@@ -237,6 +238,7 @@ machine(MachineType:Directory, "Directory protocol")
|
|||||||
// ** OUT_PORTS **
|
// ** OUT_PORTS **
|
||||||
out_port(forwardNetwork_out, RequestMsg, forwardFromDir);
|
out_port(forwardNetwork_out, RequestMsg, forwardFromDir);
|
||||||
out_port(responseNetwork_out, ResponseMsg, responseFromDir);
|
out_port(responseNetwork_out, ResponseMsg, responseFromDir);
|
||||||
|
out_port(memQueue_out, MemoryMsg, requestToMemory);
|
||||||
|
|
||||||
// ** IN_PORTS **
|
// ** IN_PORTS **
|
||||||
|
|
||||||
@@ -479,18 +481,36 @@ machine(MachineType:Directory, "Directory protocol")
|
|||||||
|
|
||||||
action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
|
action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
|
||||||
peek(requestQueue_in, RequestMsg) {
|
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") {
|
action(qw_queueMemoryWBFromCacheRequest, "qw", desc="Queue off-chip writeback request") {
|
||||||
peek(requestQueue_in, RequestMsg) {
|
peek(requestQueue_in, RequestMsg) {
|
||||||
if (is_valid(tbe)) {
|
if (is_valid(tbe)) {
|
||||||
queueMemoryWrite(tbe.Requestor, address, to_memory_controller_latency,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
in_msg.DataBlk);
|
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 {
|
} else {
|
||||||
queueMemoryWrite(in_msg.Requestor, address, to_memory_controller_latency,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
in_msg.DataBlk);
|
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;
|
DataBlock DataBlk := in_msg.DataBlk;
|
||||||
DataBlk.copyPartial(tbe.DataBlk, getOffset(tbe.PhysicalAddress),
|
DataBlk.copyPartial(tbe.DataBlk, getOffset(tbe.PhysicalAddress),
|
||||||
tbe.Len);
|
tbe.Len);
|
||||||
queueMemoryWrite(tbe.Requestor, address, to_memory_controller_latency,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
DataBlk);
|
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") {
|
action(qw_queueMemoryWBFromDMARequest, "/qw", desc="Queue off-chip writeback request") {
|
||||||
peek(requestQueue_in, RequestMsg) {
|
peek(requestQueue_in, RequestMsg) {
|
||||||
queueMemoryWrite(in_msg.Requestor, address, to_memory_controller_latency,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
in_msg.DataBlk);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ machine(MachineType:Directory, "Token protocol")
|
|||||||
MessageBuffer * dmaRequestToDir, network="From", virtual_network="0",
|
MessageBuffer * dmaRequestToDir, network="From", virtual_network="0",
|
||||||
vnet_type="request";
|
vnet_type="request";
|
||||||
|
|
||||||
|
MessageBuffer * requestToMemory;
|
||||||
MessageBuffer * responseFromMemory;
|
MessageBuffer * responseFromMemory;
|
||||||
{
|
{
|
||||||
// STATES
|
// STATES
|
||||||
@@ -276,6 +277,7 @@ machine(MachineType:Directory, "Token protocol")
|
|||||||
out_port(persistentNetwork_out, PersistentMsg, persistentFromDir);
|
out_port(persistentNetwork_out, PersistentMsg, persistentFromDir);
|
||||||
out_port(requestNetwork_out, RequestMsg, requestFromDir);
|
out_port(requestNetwork_out, RequestMsg, requestFromDir);
|
||||||
out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir);
|
out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir);
|
||||||
|
out_port(memQueue_out, MemoryMsg, requestToMemory);
|
||||||
|
|
||||||
// ** IN_PORTS **
|
// ** IN_PORTS **
|
||||||
// off-chip memory request/response is done
|
// 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") {
|
action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
|
||||||
peek(requestNetwork_in, RequestMsg) {
|
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") {
|
action(qp_queueMemoryForPersistent, "qp", desc="Queue off-chip fetch request") {
|
||||||
queueMemoryRead(persistentTable.findSmallest(address), address,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
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") {
|
action(fd_memoryDma, "fd", desc="Queue off-chip fetch request") {
|
||||||
peek(dmaRequestQueue_in, DMARequestMsg) {
|
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") {
|
action(lq_queueMemoryWbRequest, "lq", desc="Write data to memory") {
|
||||||
peek(responseNetwork_in, ResponseMsg) {
|
peek(responseNetwork_in, ResponseMsg) {
|
||||||
queueMemoryWrite(in_msg.Sender, address, to_memory_controller_latency,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
in_msg.DataBlk);
|
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") {
|
action(ld_queueMemoryDmaWriteFromTbe, "ld", desc="Write DMA data to memory") {
|
||||||
queueMemoryWritePartial(tbe.DmaRequestor, address,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
to_memory_controller_latency, tbe.DataBlk,
|
out_msg.addr := address;
|
||||||
tbe.Len);
|
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",
|
action(lr_queueMemoryDmaReadWriteback, "lr",
|
||||||
desc="Write DMA data from read to memory") {
|
desc="Write DMA data from read to memory") {
|
||||||
peek(responseNetwork_in, ResponseMsg) {
|
peek(responseNetwork_in, ResponseMsg) {
|
||||||
queueMemoryWrite(machineID, address, to_memory_controller_latency,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
in_msg.DataBlk);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ machine(MachineType:Directory, "AMD Hammer-like protocol")
|
|||||||
vnet_type="request";
|
vnet_type="request";
|
||||||
|
|
||||||
MessageBuffer * triggerQueue;
|
MessageBuffer * triggerQueue;
|
||||||
|
MessageBuffer * requestToMemory;
|
||||||
MessageBuffer * responseFromMemory;
|
MessageBuffer * responseFromMemory;
|
||||||
{
|
{
|
||||||
// STATES
|
// STATES
|
||||||
@@ -304,12 +305,13 @@ machine(MachineType:Directory, "AMD Hammer-like protocol")
|
|||||||
// ** OUT_PORTS **
|
// ** OUT_PORTS **
|
||||||
out_port(requestQueue_out, ResponseMsg, requestToDir); // For recycling requests
|
out_port(requestQueue_out, ResponseMsg, requestToDir); // For recycling requests
|
||||||
out_port(forwardNetwork_out, RequestMsg, forwardFromDir);
|
out_port(forwardNetwork_out, RequestMsg, forwardFromDir);
|
||||||
|
out_port(memQueue_out, MemoryMsg, requestToMemory);
|
||||||
out_port(responseNetwork_out, ResponseMsg, responseFromDir);
|
out_port(responseNetwork_out, ResponseMsg, responseFromDir);
|
||||||
out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir);
|
out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir);
|
||||||
out_port(triggerQueue_out, TriggerMsg, triggerQueue);
|
out_port(triggerQueue_out, TriggerMsg, triggerQueue);
|
||||||
|
|
||||||
// ** IN_PORTS **
|
// ** IN_PORTS **
|
||||||
|
|
||||||
// Trigger Queue
|
// Trigger Queue
|
||||||
in_port(triggerQueue_in, TriggerMsg, triggerQueue, rank=5) {
|
in_port(triggerQueue_in, TriggerMsg, triggerQueue, rank=5) {
|
||||||
if (triggerQueue_in.isReady(clockEdge())) {
|
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") {
|
action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
|
||||||
peek(requestQueue_in, RequestMsg) {
|
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") {
|
action(qd_queueMemoryRequestFromDmaRead, "qd", desc="Queue off-chip fetch request") {
|
||||||
peek(dmaRequestQueue_in, DMARequestMsg) {
|
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") {
|
action(l_queueMemoryWBRequest, "lq", desc="Write PUTX data to memory") {
|
||||||
peek(unblockNetwork_in, ResponseMsg) {
|
peek(unblockNetwork_in, ResponseMsg) {
|
||||||
queueMemoryWrite(in_msg.Sender, address, to_memory_controller_latency,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
in_msg.DataBlk);
|
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") {
|
action(ld_queueMemoryDmaWrite, "ld", desc="Write DMA data to memory") {
|
||||||
assert(is_valid(tbe));
|
assert(is_valid(tbe));
|
||||||
queueMemoryWritePartial(tbe.DmaRequestor, tbe.PhysicalAddress,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
to_memory_controller_latency, tbe.DmaDataBlk,
|
out_msg.addr := tbe.PhysicalAddress;
|
||||||
tbe.Len);
|
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") {
|
action(ly_queueMemoryWriteFromTBE, "ly", desc="Write data to memory from TBE") {
|
||||||
queueMemoryWrite(machineID, address, to_memory_controller_latency,
|
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
|
||||||
tbe.DataBlk);
|
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") {
|
action(ll_checkIncomingWriteback, "\l", desc="Check PUTX/PUTO response message") {
|
||||||
|
|||||||
@@ -32,15 +32,6 @@ MachineID machineID;
|
|||||||
NodeID clusterID;
|
NodeID clusterID;
|
||||||
Cycles recycle_latency;
|
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
|
// Functions implemented in the AbstractController class for
|
||||||
// making functional access to the memory maintained by the
|
// making functional access to the memory maintained by the
|
||||||
// memory controllers.
|
// memory controllers.
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ structure(MemoryMsg, desc="...", interface="Message") {
|
|||||||
MachineID OriginalRequestorMachId, desc="What component originally requested";
|
MachineID OriginalRequestorMachId, desc="What component originally requested";
|
||||||
DataBlock DataBlk, desc="Data to writeback";
|
DataBlock DataBlk, desc="Data to writeback";
|
||||||
MessageSizeType MessageSize, desc="size category of the message";
|
MessageSizeType MessageSize, desc="size category of the message";
|
||||||
|
int Len, desc="size of the memory/dma request";
|
||||||
// Not all fields used by all protocols:
|
// Not all fields used by all protocols:
|
||||||
PrefetchBit Prefetch, desc="Is this a prefetch request";
|
PrefetchBit Prefetch, desc="Is this a prefetch request";
|
||||||
bool ReadX, desc="Exclusive";
|
bool ReadX, desc="Exclusive";
|
||||||
|
|||||||
@@ -76,6 +76,10 @@ AbstractController::init()
|
|||||||
m_delayVCHistogram.push_back(new Stats::Histogram());
|
m_delayVCHistogram.push_back(new Stats::Histogram());
|
||||||
m_delayVCHistogram[i]->init(10);
|
m_delayVCHistogram[i]->init(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getMemReqQueue()) {
|
||||||
|
getMemReqQueue()->setConsumer(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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
|
void
|
||||||
AbstractController::blockOnQueue(Addr addr, MessageBuffer* port)
|
AbstractController::blockOnQueue(Addr addr, MessageBuffer* port)
|
||||||
{
|
{
|
||||||
@@ -236,73 +295,6 @@ AbstractController::getPort(const std::string &if_name, PortID idx)
|
|||||||
return memoryPort;
|
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
|
void
|
||||||
AbstractController::functionalMemoryRead(PacketPtr pkt)
|
AbstractController::functionalMemoryRead(PacketPtr pkt)
|
||||||
{
|
{
|
||||||
@@ -327,7 +319,7 @@ AbstractController::functionalMemoryWrite(PacketPtr pkt)
|
|||||||
void
|
void
|
||||||
AbstractController::recvTimingResp(PacketPtr pkt)
|
AbstractController::recvTimingResp(PacketPtr pkt)
|
||||||
{
|
{
|
||||||
assert(getMemoryQueue());
|
assert(getMemRespQueue());
|
||||||
assert(pkt->isResponse());
|
assert(pkt->isResponse());
|
||||||
|
|
||||||
std::shared_ptr<MemoryMsg> msg = std::make_shared<MemoryMsg>(clockEdge());
|
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!");
|
panic("Incorrect packet type received from memory controller!");
|
||||||
}
|
}
|
||||||
|
|
||||||
getMemoryQueue()->enqueue(msg, clockEdge(), cyclesToTicks(Cycles(1)));
|
getMemRespQueue()->enqueue(msg, clockEdge(), cyclesToTicks(Cycles(1)));
|
||||||
delete pkt;
|
delete pkt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,8 @@ class AbstractController : public ClockedObject, public Consumer
|
|||||||
bool isBlocked(Addr);
|
bool isBlocked(Addr);
|
||||||
|
|
||||||
virtual MessageBuffer* getMandatoryQueue() const = 0;
|
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 AccessPermission getAccessPermission(const Addr &addr) = 0;
|
||||||
|
|
||||||
virtual void print(std::ostream & out) const = 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,
|
Port &getPort(const std::string &if_name,
|
||||||
PortID idx=InvalidPortID);
|
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);
|
void recvTimingResp(PacketPtr pkt);
|
||||||
Tick recvAtomic(PacketPtr pkt);
|
Tick recvAtomic(PacketPtr pkt);
|
||||||
|
|
||||||
@@ -178,6 +174,7 @@ class AbstractController : public ClockedObject, public Consumer
|
|||||||
void wakeUpBuffers(Addr addr);
|
void wakeUpBuffers(Addr addr);
|
||||||
void wakeUpAllBuffers(Addr addr);
|
void wakeUpAllBuffers(Addr addr);
|
||||||
void wakeUpAllBuffers();
|
void wakeUpAllBuffers();
|
||||||
|
bool serviceMemoryQueue();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const NodeID m_version;
|
const NodeID m_version;
|
||||||
|
|||||||
@@ -299,7 +299,8 @@ class $c_ident : public AbstractController
|
|||||||
void init();
|
void init();
|
||||||
|
|
||||||
MessageBuffer *getMandatoryQueue() const;
|
MessageBuffer *getMandatoryQueue() const;
|
||||||
MessageBuffer *getMemoryQueue() const;
|
MessageBuffer *getMemReqQueue() const;
|
||||||
|
MessageBuffer *getMemRespQueue() const;
|
||||||
void initNetQueues();
|
void initNetQueues();
|
||||||
|
|
||||||
void print(std::ostream& out) const;
|
void print(std::ostream& out) const;
|
||||||
@@ -672,6 +673,11 @@ $c_ident::init()
|
|||||||
if port.code.find("mandatoryQueue_ptr") >= 0:
|
if port.code.find("mandatoryQueue_ptr") >= 0:
|
||||||
mq_ident = "m_mandatoryQueue_ptr"
|
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"
|
memq_ident = "NULL"
|
||||||
for port in self.in_ports:
|
for port in self.in_ports:
|
||||||
if port.code.find("responseFromMemory_ptr") >= 0:
|
if port.code.find("responseFromMemory_ptr") >= 0:
|
||||||
@@ -854,7 +860,13 @@ $c_ident::getMandatoryQueue() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
MessageBuffer*
|
MessageBuffer*
|
||||||
$c_ident::getMemoryQueue() const
|
$c_ident::getMemReqQueue() const
|
||||||
|
{
|
||||||
|
return $memoutq_ident;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageBuffer*
|
||||||
|
$c_ident::getMemRespQueue() const
|
||||||
{
|
{
|
||||||
return $memq_ident;
|
return $memq_ident;
|
||||||
}
|
}
|
||||||
@@ -1085,6 +1097,10 @@ using namespace std;
|
|||||||
void
|
void
|
||||||
${ident}_Controller::wakeup()
|
${ident}_Controller::wakeup()
|
||||||
{
|
{
|
||||||
|
if (getMemReqQueue() && getMemReqQueue()->isReady(clockEdge())) {
|
||||||
|
serviceMemoryQueue();
|
||||||
|
}
|
||||||
|
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
unsigned char rejected[${{len(msg_bufs)}}];
|
unsigned char rejected[${{len(msg_bufs)}}];
|
||||||
|
|||||||
Reference in New Issue
Block a user