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):
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):
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)
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)
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)
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)
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()
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()
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()
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()
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()
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;
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())) {
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;
+ }
}
}
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;
+ }
}
}
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;
+ }
}
}
MessageBuffer * responseFromDir, network="To", virtual_network="1",
vnet_type="response";
+ MessageBuffer * requestToMemory;
MessageBuffer * responseFromMemory;
{
// STATES
// ** OUT_PORTS **
out_port(responseNetwork_out, ResponseMsg, responseFromDir);
+ out_port(memQueue_out, MemoryMsg, requestToMemory);
// ** IN_PORTS **
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;
+ }
}
}
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;
+ }
}
}
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;
+ }
}
}
vnet_type="request";
MessageBuffer * dmaRequestToDir, network="From", virtual_network="0",
vnet_type="request";
+
+ MessageBuffer * requestToMemory;
MessageBuffer * responseFromMemory;
{
// STATES
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) {
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;
+ }
}
}
MessageBuffer * triggerQueue;
MessageBuffer * L3triggerQueue;
+
+ MessageBuffer * requestToMemory;
MessageBuffer * responseFromMemory;
{
// STATES
out_port(triggerQueue_out, TriggerMsg, triggerQueue);
out_port(L3TriggerQueue_out, TriggerMsg, L3triggerQueue);
+ out_port(memQueue_out, MemoryMsg, requestToMemory);
+
// ** IN_PORTS **
// Trigger Queue
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;
+ }
}
}
}
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;
+ }
}
}
}
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));
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));
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));
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));
MessageBuffer * triggerQueue;
MessageBuffer * L3triggerQueue;
+
+ MessageBuffer * requestToMemory;
MessageBuffer * responseFromMemory;
{
// STATES
out_port(triggerQueue_out, TriggerMsg, triggerQueue);
out_port(L3TriggerQueue_out, TriggerMsg, L3triggerQueue);
+ out_port(memQueue_out, MemoryMsg, requestToMemory);
+
// ** IN_PORTS **
// Trigger Queue
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;
+ }
}
}
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;
+ }
}
}
}
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));
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));
MessageBuffer * triggerQueue, ordered="true";
MessageBuffer * L3triggerQueue, ordered="true";
+
+ MessageBuffer * requestToMemory;
MessageBuffer * responseFromMemory;
{
// STATES
out_port(triggerQueue_out, TriggerMsg, triggerQueue);
out_port(L3TriggerQueue_out, TriggerMsg, L3triggerQueue);
+ out_port(memQueue_out, MemoryMsg, requestToMemory);
+
// ** IN_PORTS **
// Trigger Queue
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;
+ }
}
}
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;
+ }
}
}
}
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));
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));
MessageBuffer * responseFromDir, network="To", virtual_network="2",
vnet_type="response"; // Dir -> mod-L2 bank
+ MessageBuffer * requestToMemory;
MessageBuffer * responseFromMemory;
{
// STATES
// ** OUT_PORTS **
out_port(forwardNetwork_out, RequestMsg, forwardFromDir);
out_port(responseNetwork_out, ResponseMsg, responseFromDir);
+ out_port(memQueue_out, MemoryMsg, requestToMemory);
// ** IN_PORTS **
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;
+ }
}
}
}
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;
+ }
}
}
MessageBuffer * dmaRequestToDir, network="From", virtual_network="0",
vnet_type="request";
+ MessageBuffer * requestToMemory;
MessageBuffer * responseFromMemory;
{
// STATES
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
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;
+ }
}
}
vnet_type="request";
MessageBuffer * triggerQueue;
+ MessageBuffer * requestToMemory;
MessageBuffer * responseFromMemory;
{
// STATES
// ** 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())) {
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;
+ }
}
}
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") {
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.
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";
m_delayVCHistogram.push_back(new Stats::Histogram());
m_delayVCHistogram[i]->init(10);
}
+
+ if (getMemReqQueue()) {
+ getMemReqQueue()->setConsumer(this);
+ }
}
void
}
}
+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)
{
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)
{
void
AbstractController::recvTimingResp(PacketPtr pkt)
{
- assert(getMemoryQueue());
+ assert(getMemRespQueue());
assert(pkt->isResponse());
std::shared_ptr<MemoryMsg> msg = std::make_shared<MemoryMsg>(clockEdge());
panic("Incorrect packet type received from memory controller!");
}
- getMemoryQueue()->enqueue(msg, clockEdge(), cyclesToTicks(Cycles(1)));
+ getMemRespQueue()->enqueue(msg, clockEdge(), cyclesToTicks(Cycles(1)));
delete pkt;
}
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;
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);
void wakeUpBuffers(Addr addr);
void wakeUpAllBuffers(Addr addr);
void wakeUpAllBuffers();
+ bool serviceMemoryQueue();
protected:
const NodeID m_version;
void init();
MessageBuffer *getMandatoryQueue() const;
- MessageBuffer *getMemoryQueue() const;
+ MessageBuffer *getMemReqQueue() const;
+ MessageBuffer *getMemRespQueue() const;
void initNetQueues();
void print(std::ostream& out) const;
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:
}
MessageBuffer*
-$c_ident::getMemoryQueue() const
+$c_ident::getMemReqQueue() const
+{
+ return $memoutq_ident;
+}
+
+MessageBuffer*
+$c_ident::getMemRespQueue() const
{
return $memq_ident;
}
void
${ident}_Controller::wakeup()
{
+ if (getMemReqQueue() && getMemReqQueue()->isReady(clockEdge())) {
+ serviceMemoryQueue();
+ }
+
int counter = 0;
while (true) {
unsigned char rejected[${{len(msg_bufs)}}];