From 53b6e21c631a0bb227aae0b474884022ed191f59 Mon Sep 17 00:00:00 2001 From: Matt Poremba Date: Thu, 8 Feb 2018 11:48:21 -0800 Subject: [PATCH] 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 Reviewed-by: Bradford Beckmann Reviewed-by: Jason Lowe-Power Reviewed-by: Matt Sinclair Maintainer: Bradford Beckmann --- configs/learning_gem5/part3/msi_caches.py | 9 +- .../part3/ruby_caches_MI_example.py | 1 + configs/ruby/GPU_RfO.py | 1 + configs/ruby/GPU_VIPER.py | 1 + configs/ruby/GPU_VIPER_Baseline.py | 1 + configs/ruby/GPU_VIPER_Region.py | 1 + configs/ruby/MESI_Two_Level.py | 1 + configs/ruby/MI_example.py | 1 + configs/ruby/MOESI_CMP_directory.py | 1 + configs/ruby/MOESI_CMP_token.py | 1 + configs/ruby/MOESI_hammer.py | 1 + src/learning_gem5/part3/MSI-dir.sm | 39 ++++-- src/mem/ruby/protocol/MESI_Two_Level-dir.sm | 48 +++++-- src/mem/ruby/protocol/MI_example-dir.sm | 51 +++++-- .../protocol/MOESI_AMD_Base-Region-dir.sm | 54 ++++++-- src/mem/ruby/protocol/MOESI_AMD_Base-dir.sm | 38 ++++- .../protocol/MOESI_AMD_Base-probeFilter.sm | 38 ++++- .../ruby/protocol/MOESI_CMP_directory-dir.sm | 50 +++++-- src/mem/ruby/protocol/MOESI_CMP_token-dir.sm | 58 ++++++-- src/mem/ruby/protocol/MOESI_hammer-dir.sm | 53 +++++-- src/mem/ruby/protocol/RubySlicc_Defines.sm | 9 -- src/mem/ruby/protocol/RubySlicc_MemControl.sm | 1 + .../slicc_interface/AbstractController.cc | 130 ++++++++---------- .../slicc_interface/AbstractController.hh | 9 +- src/mem/slicc/symbols/StateMachine.py | 20 ++- 25 files changed, 445 insertions(+), 172 deletions(-) diff --git a/configs/learning_gem5/part3/msi_caches.py b/configs/learning_gem5/part3/msi_caches.py index aeacd7594..f8994265c 100644 --- a/configs/learning_gem5/part3/msi_caches.py +++ b/configs/learning_gem5/part3/msi_caches.py @@ -214,10 +214,11 @@ class DirController(Directory_Controller): self.forwardToCache = MessageBuffer(ordered = True) self.forwardToCache.master = ruby_system.network.slave - # This is another special message buffer. It is used to send replies - # from memory back to the controller. Any messages received on the - # memory port (see self.memory above) will be directed to this - # message buffer. + # These are other special message buffers. They are used to send + # requests to memory and responses from memory back to the controller. + # Any messages sent or received on the memory port (see self.memory + # above) will be directed through these message buffers. + self.requestToMemory = MessageBuffer() self.responseFromMemory = MessageBuffer() class MyNetwork(SimpleNetwork): diff --git a/configs/learning_gem5/part3/ruby_caches_MI_example.py b/configs/learning_gem5/part3/ruby_caches_MI_example.py index 0a7e0d4c4..29b66a6d4 100644 --- a/configs/learning_gem5/part3/ruby_caches_MI_example.py +++ b/configs/learning_gem5/part3/ruby_caches_MI_example.py @@ -204,6 +204,7 @@ class DirController(Directory_Controller): self.dmaResponseFromDir.master = ruby_system.network.slave self.forwardFromDir = MessageBuffer() self.forwardFromDir.master = ruby_system.network.slave + self.requestToMemory = MessageBuffer() self.responseFromMemory = MessageBuffer() class MyNetwork(SimpleNetwork): diff --git a/configs/ruby/GPU_RfO.py b/configs/ruby/GPU_RfO.py index 449c169b2..cf2fdbd82 100644 --- a/configs/ruby/GPU_RfO.py +++ b/configs/ruby/GPU_RfO.py @@ -499,6 +499,7 @@ def create_system(options, full_system, system, dma_devices, bootmem, dir_cntrl.triggerQueue = MessageBuffer(ordered = True) dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True) + dir_cntrl.requestToMemory = MessageBuffer() dir_cntrl.responseFromMemory = MessageBuffer() exec("system.dir_cntrl%d = dir_cntrl" % i) diff --git a/configs/ruby/GPU_VIPER.py b/configs/ruby/GPU_VIPER.py index 2c364263f..71238ae6a 100644 --- a/configs/ruby/GPU_VIPER.py +++ b/configs/ruby/GPU_VIPER.py @@ -453,6 +453,7 @@ def create_system(options, full_system, system, dma_devices, bootmem, dir_cntrl.triggerQueue = MessageBuffer(ordered = True) dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True) + dir_cntrl.requestToMemory = MessageBuffer() dir_cntrl.responseFromMemory = MessageBuffer() exec("ruby_system.dir_cntrl%d = dir_cntrl" % i) diff --git a/configs/ruby/GPU_VIPER_Baseline.py b/configs/ruby/GPU_VIPER_Baseline.py index f4d914704..5f3199021 100644 --- a/configs/ruby/GPU_VIPER_Baseline.py +++ b/configs/ruby/GPU_VIPER_Baseline.py @@ -431,6 +431,7 @@ def create_system(options, full_system, system, dma_devices, bootmem, dir_cntrl.triggerQueue = MessageBuffer(ordered = True) dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True) + dir_cntrl.requestToMemory = MessageBuffer() dir_cntrl.responseFromMemory = MessageBuffer() exec("system.dir_cntrl%d = dir_cntrl" % i) diff --git a/configs/ruby/GPU_VIPER_Region.py b/configs/ruby/GPU_VIPER_Region.py index 2bcd8c41c..47517a19e 100644 --- a/configs/ruby/GPU_VIPER_Region.py +++ b/configs/ruby/GPU_VIPER_Region.py @@ -711,6 +711,7 @@ def create_system(options, full_system, system, dma_devices, bootmem, dir_cntrl.triggerQueue = MessageBuffer(ordered = True) dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True) + dir_cntrl.requestToMemory = MessageBuffer() dir_cntrl.responseFromMemory = MessageBuffer() exec("system.dir_cntrl%d = dir_cntrl" % i) diff --git a/configs/ruby/MESI_Two_Level.py b/configs/ruby/MESI_Two_Level.py index fc8f2f2f1..8d2e01fb6 100644 --- a/configs/ruby/MESI_Two_Level.py +++ b/configs/ruby/MESI_Two_Level.py @@ -185,6 +185,7 @@ def create_system(options, full_system, system, dma_ports, bootmem, dir_cntrl.responseToDir.slave = ruby_system.network.master dir_cntrl.responseFromDir = MessageBuffer() dir_cntrl.responseFromDir.master = ruby_system.network.slave + dir_cntrl.requestToMemory = MessageBuffer() dir_cntrl.responseFromMemory = MessageBuffer() diff --git a/configs/ruby/MI_example.py b/configs/ruby/MI_example.py index 4f17f51b0..2ea6699d8 100644 --- a/configs/ruby/MI_example.py +++ b/configs/ruby/MI_example.py @@ -142,6 +142,7 @@ def create_system(options, full_system, system, dma_ports, bootmem, dir_cntrl.dmaResponseFromDir.master = ruby_system.network.slave dir_cntrl.forwardFromDir = MessageBuffer() dir_cntrl.forwardFromDir.master = ruby_system.network.slave + dir_cntrl.requestToMemory = MessageBuffer() dir_cntrl.responseFromMemory = MessageBuffer() diff --git a/configs/ruby/MOESI_CMP_directory.py b/configs/ruby/MOESI_CMP_directory.py index a86752e65..2b7770a94 100644 --- a/configs/ruby/MOESI_CMP_directory.py +++ b/configs/ruby/MOESI_CMP_directory.py @@ -209,6 +209,7 @@ def create_system(options, full_system, system, dma_ports, bootmem, dir_cntrl.responseFromDir.master = ruby_system.network.slave dir_cntrl.forwardFromDir = MessageBuffer() dir_cntrl.forwardFromDir.master = ruby_system.network.slave + dir_cntrl.requestToMemory = MessageBuffer() dir_cntrl.responseFromMemory = MessageBuffer() diff --git a/configs/ruby/MOESI_CMP_token.py b/configs/ruby/MOESI_CMP_token.py index eadca5bdd..a2c41c08a 100644 --- a/configs/ruby/MOESI_CMP_token.py +++ b/configs/ruby/MOESI_CMP_token.py @@ -214,6 +214,7 @@ def create_system(options, full_system, system, dma_ports, bootmem, dir_cntrl.persistentFromDir.master = ruby_system.network.slave dir_cntrl.dmaResponseFromDir = MessageBuffer(ordered = True) dir_cntrl.dmaResponseFromDir.master = ruby_system.network.slave + dir_cntrl.requestToMemory = MessageBuffer() dir_cntrl.responseFromMemory = MessageBuffer() diff --git a/configs/ruby/MOESI_hammer.py b/configs/ruby/MOESI_hammer.py index 12a308e3e..5aac38b3e 100644 --- a/configs/ruby/MOESI_hammer.py +++ b/configs/ruby/MOESI_hammer.py @@ -206,6 +206,7 @@ def create_system(options, full_system, system, dma_ports, bootmem, dir_cntrl.requestToDir.slave = ruby_system.network.master dir_cntrl.dmaRequestToDir = MessageBuffer(ordered = True) dir_cntrl.dmaRequestToDir.slave = ruby_system.network.master + dir_cntrl.requestToMemory = MessageBuffer() dir_cntrl.responseFromMemory = MessageBuffer() diff --git a/src/learning_gem5/part3/MSI-dir.sm b/src/learning_gem5/part3/MSI-dir.sm index d412d0982..ca5ea3e53 100644 --- a/src/learning_gem5/part3/MSI-dir.sm +++ b/src/learning_gem5/part3/MSI-dir.sm @@ -74,6 +74,9 @@ machine(MachineType:Directory, "Directory protocol") MessageBuffer *responseFromCache, network="From", virtual_network="2", vnet_type="response"; + // Special buffer for memory requests. Kind of like the mandatory queue + MessageBuffer *requestToMemory; + // Special buffer for memory responses. Kind of like the mandatory queue MessageBuffer *responseFromMemory; @@ -209,6 +212,7 @@ machine(MachineType:Directory, "Directory protocol") out_port(forward_out, RequestMsg, forwardToCache); out_port(response_out, ResponseMsg, responseToCache); + out_port(memQueue_out, MemoryMsg, requestToMemory); in_port(memQueue_in, MemoryMsg, responseFromMemory) { if (memQueue_in.isReady(clockEdge())) { @@ -279,11 +283,16 @@ machine(MachineType:Directory, "Directory protocol") action(sendMemRead, "r", desc="Send a memory read request") { peek(request_in, RequestMsg) { - // Special function from AbstractController that will send a new - // packet out of the "Ruby" black box to the memory side. At some - // point the response will be on the memory queue. - // Like enqeue, this takes a latency for the request. - queueMemoryRead(in_msg.Requestor, address, toMemLatency); + // Send request through special memory request queue. At some + // point the response will be on the memory response queue. + // Like enqueue, this takes a latency for the request. + enqueue(memQueue_out, MemoryMsg, toMemLatency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := in_msg.Requestor; + out_msg.MessageSize := MessageSizeType:Request_Control; + out_msg.Len := 0; + } } } @@ -291,8 +300,14 @@ machine(MachineType:Directory, "Directory protocol") peek(request_in, RequestMsg) { DPRINTF(RubySlicc, "Writing memory for %#x\n", address); DPRINTF(RubySlicc, "Writing %s\n", in_msg.DataBlk); - queueMemoryWrite(in_msg.Requestor, address, toMemLatency, - in_msg.DataBlk); + enqueue(memQueue_out, MemoryMsg, toMemLatency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := in_msg.Requestor; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Len := 0; + } } } @@ -300,8 +315,14 @@ machine(MachineType:Directory, "Directory protocol") peek(response_in, ResponseMsg) { DPRINTF(RubySlicc, "Writing memory for %#x\n", address); DPRINTF(RubySlicc, "Writing %s\n", in_msg.DataBlk); - queueMemoryWrite(in_msg.Sender, address, toMemLatency, - in_msg.DataBlk); + enqueue(memQueue_out, MemoryMsg, toMemLatency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := in_msg.Sender; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Len := 0; + } } } diff --git a/src/mem/ruby/protocol/MESI_Two_Level-dir.sm b/src/mem/ruby/protocol/MESI_Two_Level-dir.sm index 2e935de66..9d6975570 100644 --- a/src/mem/ruby/protocol/MESI_Two_Level-dir.sm +++ b/src/mem/ruby/protocol/MESI_Two_Level-dir.sm @@ -38,6 +38,7 @@ machine(MachineType:Directory, "MESI Two Level directory protocol") MessageBuffer * responseFromDir, network="To", virtual_network="1", vnet_type="response"; + MessageBuffer * requestToMemory; MessageBuffer * responseFromMemory; { // STATES @@ -189,6 +190,7 @@ machine(MachineType:Directory, "MESI Two Level directory protocol") // ** OUT_PORTS ** out_port(responseNetwork_out, ResponseMsg, responseFromDir); + out_port(memQueue_out, MemoryMsg, requestToMemory); // ** IN_PORTS ** @@ -306,21 +308,39 @@ machine(MachineType:Directory, "MESI Two Level directory protocol") action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") { peek(requestNetwork_in, RequestMsg) { - queueMemoryRead(in_msg.Requestor, address, to_mem_ctrl_latency); + enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := in_msg.Requestor; + out_msg.MessageSize := MessageSizeType:Request_Control; + out_msg.Len := 0; + } } } action(qw_queueMemoryWBRequest, "qw", desc="Queue off-chip writeback request") { peek(responseNetwork_in, ResponseMsg) { - queueMemoryWrite(in_msg.Sender, address, to_mem_ctrl_latency, - in_msg.DataBlk); + enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := in_msg.Sender; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Len := 0; + } } } //added by SS for dma action(qf_queueMemoryFetchRequestDMA, "qfd", desc="Queue off-chip fetch request") { peek(requestNetwork_in, RequestMsg) { - queueMemoryRead(in_msg.Requestor, address, to_mem_ctrl_latency); + enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := in_msg.Requestor; + out_msg.MessageSize := MessageSizeType:Request_Control; + out_msg.Len := 0; + } } } @@ -344,8 +364,14 @@ machine(MachineType:Directory, "MESI Two Level directory protocol") action(qw_queueMemoryWBRequest_partial, "qwp", desc="Queue off-chip writeback request") { peek(requestNetwork_in, RequestMsg) { - queueMemoryWritePartial(machineID, address, to_mem_ctrl_latency, - in_msg.DataBlk, in_msg.Len); + enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := machineID; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Len := in_msg.Len; + } } } @@ -407,8 +433,14 @@ machine(MachineType:Directory, "MESI Two Level directory protocol") action(qw_queueMemoryWBRequest_partialTBE, "qwt", desc="Queue off-chip writeback request") { peek(responseNetwork_in, ResponseMsg) { - queueMemoryWritePartial(in_msg.Sender, tbe.PhysicalAddress, - to_mem_ctrl_latency, tbe.DataBlk, tbe.Len); + enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) { + out_msg.addr := tbe.PhysicalAddress; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := in_msg.Sender; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := tbe.DataBlk; + out_msg.Len := tbe.Len; + } } } diff --git a/src/mem/ruby/protocol/MI_example-dir.sm b/src/mem/ruby/protocol/MI_example-dir.sm index 471608de0..ed315e898 100644 --- a/src/mem/ruby/protocol/MI_example-dir.sm +++ b/src/mem/ruby/protocol/MI_example-dir.sm @@ -43,6 +43,8 @@ machine(MachineType:Directory, "Directory protocol") vnet_type="request"; MessageBuffer * dmaRequestToDir, network="From", virtual_network="0", vnet_type="request"; + + MessageBuffer * requestToMemory; MessageBuffer * responseFromMemory; { // STATES @@ -204,6 +206,7 @@ machine(MachineType:Directory, "Directory protocol") out_port(responseNetwork_out, ResponseMsg, responseFromDir); out_port(requestQueue_out, ResponseMsg, requestToDir); // For recycling requests out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir); + out_port(memQueue_out, MemoryMsg, requestToMemory); // ** IN_PORTS ** in_port(dmaRequestQueue_in, DMARequestMsg, dmaRequestToDir) { @@ -445,36 +448,64 @@ machine(MachineType:Directory, "Directory protocol") action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") { peek(requestQueue_in, RequestMsg) { - queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := in_msg.Requestor; + out_msg.MessageSize := MessageSizeType:Request_Control; + out_msg.Len := 0; + } } } action(qf_queueMemoryFetchRequestDMA, "qfd", desc="Queue off-chip fetch request") { peek(dmaRequestQueue_in, DMARequestMsg) { - queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := in_msg.Requestor; + out_msg.MessageSize := MessageSizeType:Request_Control; + out_msg.Len := 0; + } } } action(qw_queueMemoryWBRequest_partial, "qwp", desc="Queue off-chip writeback request") { peek(dmaRequestQueue_in, DMARequestMsg) { - queueMemoryWritePartial(in_msg.Requestor, address, - to_memory_controller_latency, in_msg.DataBlk, - in_msg.Len); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := in_msg.Requestor; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Len := in_msg.Len; + } } } action(qw_queueMemoryWBRequest_partialTBE, "qwt", desc="Queue off-chip writeback request") { peek(requestQueue_in, RequestMsg) { - queueMemoryWritePartial(in_msg.Requestor, address, - to_memory_controller_latency, tbe.DataBlk, - tbe.Len); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := in_msg.Requestor; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := tbe.DataBlk; + out_msg.Len := tbe.Len; + } } } action(l_queueMemoryWBRequest, "lq", desc="Write PUTX data to memory") { peek(requestQueue_in, RequestMsg) { - queueMemoryWrite(in_msg.Requestor, address, to_memory_controller_latency, - in_msg.DataBlk); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := in_msg.Requestor; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Len := 0; + } } } diff --git a/src/mem/ruby/protocol/MOESI_AMD_Base-Region-dir.sm b/src/mem/ruby/protocol/MOESI_AMD_Base-Region-dir.sm index 620a139c4..3218574bf 100644 --- a/src/mem/ruby/protocol/MOESI_AMD_Base-Region-dir.sm +++ b/src/mem/ruby/protocol/MOESI_AMD_Base-Region-dir.sm @@ -59,6 +59,8 @@ machine(MachineType:Directory, "AMD_Base-like protocol") MessageBuffer * triggerQueue; MessageBuffer * L3triggerQueue; + + MessageBuffer * requestToMemory; MessageBuffer * responseFromMemory; { // STATES @@ -319,6 +321,8 @@ machine(MachineType:Directory, "AMD_Base-like protocol") out_port(triggerQueue_out, TriggerMsg, triggerQueue); out_port(L3TriggerQueue_out, TriggerMsg, L3triggerQueue); + out_port(memQueue_out, MemoryMsg, requestToMemory); + // ** IN_PORTS ** // Trigger Queue @@ -841,7 +845,12 @@ machine(MachineType:Directory, "AMD_Base-like protocol") DPRINTF(RubySlicc, "L3 data is %s\n", entry.DataBlk); L3CacheMemory.deallocate(address); } else { - queueMemoryRead(machineID, address, to_memory_controller_latency); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := machineID; + out_msg.MessageSize := MessageSizeType:Request_Control; + } } } } @@ -862,7 +871,12 @@ machine(MachineType:Directory, "AMD_Base-like protocol") DPRINTF(RubySlicc, "L3 data is %s\n", entry.DataBlk); L3CacheMemory.deallocate(address); } else { - queueMemoryRead(machineID, address, to_memory_controller_latency); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := machineID; + out_msg.MessageSize := MessageSizeType:Request_Control; + } } } } @@ -1254,8 +1268,13 @@ machine(MachineType:Directory, "AMD_Base-like protocol") Addr victim := L3CacheMemory.cacheProbe(address); CacheEntry victim_entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(victim)); - queueMemoryWrite(machineID, victim, to_memory_controller_latency, - victim_entry.DataBlk); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := victim; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := machineID; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := victim_entry.DataBlk; + } L3CacheMemory.deallocate(victim); } assert(L3CacheMemory.cacheAvail(address)); @@ -1279,8 +1298,13 @@ machine(MachineType:Directory, "AMD_Base-like protocol") Addr victim := L3CacheMemory.cacheProbe(address); CacheEntry victim_entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(victim)); - queueMemoryWrite(machineID, victim, to_memory_controller_latency, - victim_entry.DataBlk); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := victim; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := machineID; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := victim_entry.DataBlk; + } L3CacheMemory.deallocate(victim); } assert(L3CacheMemory.cacheAvail(address)); @@ -1304,8 +1328,13 @@ machine(MachineType:Directory, "AMD_Base-like protocol") Addr victim := L3CacheMemory.cacheProbe(address); CacheEntry victim_entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(victim)); - queueMemoryWrite(machineID, victim, to_memory_controller_latency, - victim_entry.DataBlk); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := victim; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := machineID; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := victim_entry.DataBlk; + } L3CacheMemory.deallocate(victim); } assert(L3CacheMemory.cacheAvail(address)); @@ -1330,8 +1359,13 @@ machine(MachineType:Directory, "AMD_Base-like protocol") Addr victim := L3CacheMemory.cacheProbe(address); CacheEntry victim_entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(victim)); - queueMemoryWrite(machineID, victim, to_memory_controller_latency, - victim_entry.DataBlk); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := victim; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := machineID; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := victim_entry.DataBlk; + } L3CacheMemory.deallocate(victim); } assert(L3CacheMemory.cacheAvail(address)); diff --git a/src/mem/ruby/protocol/MOESI_AMD_Base-dir.sm b/src/mem/ruby/protocol/MOESI_AMD_Base-dir.sm index 9737291ec..6f788ce5f 100644 --- a/src/mem/ruby/protocol/MOESI_AMD_Base-dir.sm +++ b/src/mem/ruby/protocol/MOESI_AMD_Base-dir.sm @@ -52,6 +52,8 @@ machine(MachineType:Directory, "AMD Baseline protocol") MessageBuffer * triggerQueue; MessageBuffer * L3triggerQueue; + + MessageBuffer * requestToMemory; MessageBuffer * responseFromMemory; { // STATES @@ -270,6 +272,8 @@ machine(MachineType:Directory, "AMD Baseline protocol") out_port(triggerQueue_out, TriggerMsg, triggerQueue); out_port(L3TriggerQueue_out, TriggerMsg, L3triggerQueue); + out_port(memQueue_out, MemoryMsg, requestToMemory); + // ** IN_PORTS ** // Trigger Queue @@ -516,8 +520,13 @@ machine(MachineType:Directory, "AMD Baseline protocol") action(l_queueMemWBReq, "lq", desc="Write WB data to memory") { peek(responseNetwork_in, ResponseMsg) { - queueMemoryWrite(machineID, address, to_memory_controller_latency, - in_msg.DataBlk); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := machineID; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := in_msg.DataBlk; + } } } @@ -538,7 +547,12 @@ machine(MachineType:Directory, "AMD Baseline protocol") tbe.MemData := true; L3CacheMemory.deallocate(address); } else { - queueMemoryRead(machineID, address, to_memory_controller_latency); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := machineID; + out_msg.MessageSize := MessageSizeType:Request_Control; + } } } } @@ -795,8 +809,13 @@ machine(MachineType:Directory, "AMD Baseline protocol") Addr victim := L3CacheMemory.cacheProbe(address); CacheEntry victim_entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(victim)); - queueMemoryWrite(machineID, victim, to_memory_controller_latency, - victim_entry.DataBlk); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := victim; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := machineID; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := victim_entry.DataBlk; + } L3CacheMemory.deallocate(victim); } assert(L3CacheMemory.cacheAvail(address)); @@ -821,8 +840,13 @@ machine(MachineType:Directory, "AMD Baseline protocol") Addr victim := L3CacheMemory.cacheProbe(address); CacheEntry victim_entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(victim)); - queueMemoryWrite(machineID, victim, to_memory_controller_latency, - victim_entry.DataBlk); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := victim; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := machineID; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := victim_entry.DataBlk; + } L3CacheMemory.deallocate(victim); } assert(L3CacheMemory.cacheAvail(address)); diff --git a/src/mem/ruby/protocol/MOESI_AMD_Base-probeFilter.sm b/src/mem/ruby/protocol/MOESI_AMD_Base-probeFilter.sm index bb3a7a6c7..06c293470 100644 --- a/src/mem/ruby/protocol/MOESI_AMD_Base-probeFilter.sm +++ b/src/mem/ruby/protocol/MOESI_AMD_Base-probeFilter.sm @@ -64,6 +64,8 @@ machine(MachineType:Directory, "AMD Baseline protocol") MessageBuffer * triggerQueue, ordered="true"; MessageBuffer * L3triggerQueue, ordered="true"; + + MessageBuffer * requestToMemory; MessageBuffer * responseFromMemory; { // STATES @@ -349,6 +351,8 @@ machine(MachineType:Directory, "AMD Baseline protocol") out_port(triggerQueue_out, TriggerMsg, triggerQueue); out_port(L3TriggerQueue_out, TriggerMsg, L3triggerQueue); + out_port(memQueue_out, MemoryMsg, requestToMemory); + // ** IN_PORTS ** // Trigger Queue @@ -605,8 +609,13 @@ machine(MachineType:Directory, "AMD Baseline protocol") action(l_queueMemWBReq, "lq", desc="Write WB data to memory") { peek(responseNetwork_in, ResponseMsg) { - queueMemoryWrite(machineID, address, to_memory_controller_latency, - in_msg.DataBlk); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := machineID; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := in_msg.DataBlk; + } } } @@ -625,7 +634,12 @@ machine(MachineType:Directory, "AMD Baseline protocol") tbe.MemData := true; L3CacheMemory.deallocate(address); } else { - queueMemoryRead(machineID, address, to_memory_controller_latency); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := machineID; + out_msg.MessageSize := MessageSizeType:Request_Control; + } } } } @@ -942,8 +956,13 @@ machine(MachineType:Directory, "AMD Baseline protocol") Addr victim := L3CacheMemory.cacheProbe(address); CacheEntry victim_entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(victim)); - queueMemoryWrite(machineID, victim, to_memory_controller_latency, - victim_entry.DataBlk); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := victim; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := machineID; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := victim_entry.DataBlk; + } L3CacheMemory.deallocate(victim); } assert(L3CacheMemory.cacheAvail(address)); @@ -968,8 +987,13 @@ machine(MachineType:Directory, "AMD Baseline protocol") Addr victim := L3CacheMemory.cacheProbe(address); CacheEntry victim_entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(victim)); - queueMemoryWrite(machineID, victim, to_memory_controller_latency, - victim_entry.DataBlk); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := victim; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := machineID; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := victim_entry.DataBlk; + } L3CacheMemory.deallocate(victim); } assert(L3CacheMemory.cacheAvail(address)); diff --git a/src/mem/ruby/protocol/MOESI_CMP_directory-dir.sm b/src/mem/ruby/protocol/MOESI_CMP_directory-dir.sm index 29f862e2e..7faa8e035 100644 --- a/src/mem/ruby/protocol/MOESI_CMP_directory-dir.sm +++ b/src/mem/ruby/protocol/MOESI_CMP_directory-dir.sm @@ -54,6 +54,7 @@ machine(MachineType:Directory, "Directory protocol") MessageBuffer * responseFromDir, network="To", virtual_network="2", vnet_type="response"; // Dir -> mod-L2 bank + MessageBuffer * requestToMemory; MessageBuffer * responseFromMemory; { // STATES @@ -237,6 +238,7 @@ machine(MachineType:Directory, "Directory protocol") // ** OUT_PORTS ** out_port(forwardNetwork_out, RequestMsg, forwardFromDir); out_port(responseNetwork_out, ResponseMsg, responseFromDir); + out_port(memQueue_out, MemoryMsg, requestToMemory); // ** IN_PORTS ** @@ -479,18 +481,36 @@ machine(MachineType:Directory, "Directory protocol") action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") { peek(requestQueue_in, RequestMsg) { - queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := in_msg.Requestor; + out_msg.MessageSize := MessageSizeType:Request_Control; + out_msg.Len := 0; + } } } action(qw_queueMemoryWBFromCacheRequest, "qw", desc="Queue off-chip writeback request") { peek(requestQueue_in, RequestMsg) { if (is_valid(tbe)) { - queueMemoryWrite(tbe.Requestor, address, to_memory_controller_latency, - in_msg.DataBlk); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := tbe.Requestor; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Len := 0; + } } else { - queueMemoryWrite(in_msg.Requestor, address, to_memory_controller_latency, - in_msg.DataBlk); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := in_msg.Requestor; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Len := 0; + } } } } @@ -501,15 +521,27 @@ machine(MachineType:Directory, "Directory protocol") DataBlock DataBlk := in_msg.DataBlk; DataBlk.copyPartial(tbe.DataBlk, getOffset(tbe.PhysicalAddress), tbe.Len); - queueMemoryWrite(tbe.Requestor, address, to_memory_controller_latency, - DataBlk); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := tbe.Requestor; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := DataBlk; + out_msg.Len := 0; + } } } action(qw_queueMemoryWBFromDMARequest, "/qw", desc="Queue off-chip writeback request") { peek(requestQueue_in, RequestMsg) { - queueMemoryWrite(in_msg.Requestor, address, to_memory_controller_latency, - in_msg.DataBlk); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := in_msg.Requestor; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Len := 0; + } } } diff --git a/src/mem/ruby/protocol/MOESI_CMP_token-dir.sm b/src/mem/ruby/protocol/MOESI_CMP_token-dir.sm index 2e3f12024..97ea292eb 100644 --- a/src/mem/ruby/protocol/MOESI_CMP_token-dir.sm +++ b/src/mem/ruby/protocol/MOESI_CMP_token-dir.sm @@ -61,6 +61,7 @@ machine(MachineType:Directory, "Token protocol") MessageBuffer * dmaRequestToDir, network="From", virtual_network="0", vnet_type="request"; + MessageBuffer * requestToMemory; MessageBuffer * responseFromMemory; { // STATES @@ -276,6 +277,7 @@ machine(MachineType:Directory, "Token protocol") out_port(persistentNetwork_out, PersistentMsg, persistentFromDir); out_port(requestNetwork_out, RequestMsg, requestFromDir); out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir); + out_port(memQueue_out, MemoryMsg, requestToMemory); // ** IN_PORTS ** // off-chip memory request/response is done @@ -656,39 +658,73 @@ machine(MachineType:Directory, "Token protocol") action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") { peek(requestNetwork_in, RequestMsg) { - queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := in_msg.Requestor; + out_msg.MessageSize := MessageSizeType:Request_Control; + out_msg.Len := 0; + } } } action(qp_queueMemoryForPersistent, "qp", desc="Queue off-chip fetch request") { - queueMemoryRead(persistentTable.findSmallest(address), address, - to_memory_controller_latency); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := persistentTable.findSmallest(address); + out_msg.MessageSize := MessageSizeType:Request_Control; + out_msg.Len := 0; + } } action(fd_memoryDma, "fd", desc="Queue off-chip fetch request") { peek(dmaRequestQueue_in, DMARequestMsg) { - queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := in_msg.Requestor; + out_msg.MessageSize := MessageSizeType:Request_Control; + out_msg.Len := 0; + } } } action(lq_queueMemoryWbRequest, "lq", desc="Write data to memory") { peek(responseNetwork_in, ResponseMsg) { - queueMemoryWrite(in_msg.Sender, address, to_memory_controller_latency, - in_msg.DataBlk); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := in_msg.Sender; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Len := 0; + } } } action(ld_queueMemoryDmaWriteFromTbe, "ld", desc="Write DMA data to memory") { - queueMemoryWritePartial(tbe.DmaRequestor, address, - to_memory_controller_latency, tbe.DataBlk, - tbe.Len); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := tbe.DmaRequestor; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := tbe.DataBlk; + out_msg.Len := tbe.Len; + } } action(lr_queueMemoryDmaReadWriteback, "lr", desc="Write DMA data from read to memory") { peek(responseNetwork_in, ResponseMsg) { - queueMemoryWrite(machineID, address, to_memory_controller_latency, - in_msg.DataBlk); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := machineID; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Len := 0; + } } } diff --git a/src/mem/ruby/protocol/MOESI_hammer-dir.sm b/src/mem/ruby/protocol/MOESI_hammer-dir.sm index 94a46d922..8c4c63556 100644 --- a/src/mem/ruby/protocol/MOESI_hammer-dir.sm +++ b/src/mem/ruby/protocol/MOESI_hammer-dir.sm @@ -63,6 +63,7 @@ machine(MachineType:Directory, "AMD Hammer-like protocol") vnet_type="request"; MessageBuffer * triggerQueue; + MessageBuffer * requestToMemory; MessageBuffer * responseFromMemory; { // STATES @@ -304,12 +305,13 @@ machine(MachineType:Directory, "AMD Hammer-like protocol") // ** OUT_PORTS ** out_port(requestQueue_out, ResponseMsg, requestToDir); // For recycling requests out_port(forwardNetwork_out, RequestMsg, forwardFromDir); + out_port(memQueue_out, MemoryMsg, requestToMemory); out_port(responseNetwork_out, ResponseMsg, responseFromDir); out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir); out_port(triggerQueue_out, TriggerMsg, triggerQueue); - + // ** IN_PORTS ** - + // Trigger Queue in_port(triggerQueue_in, TriggerMsg, triggerQueue, rank=5) { if (triggerQueue_in.isReady(clockEdge())) { @@ -844,13 +846,25 @@ machine(MachineType:Directory, "AMD Hammer-like protocol") action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") { peek(requestQueue_in, RequestMsg) { - queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := in_msg.Requestor; + out_msg.MessageSize := MessageSizeType:Request_Control; + out_msg.Len := 0; + } } } action(qd_queueMemoryRequestFromDmaRead, "qd", desc="Queue off-chip fetch request") { peek(dmaRequestQueue_in, DMARequestMsg) { - queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := in_msg.Requestor; + out_msg.MessageSize := MessageSizeType:Request_Control; + out_msg.Len := 0; + } } } @@ -1204,21 +1218,38 @@ machine(MachineType:Directory, "AMD Hammer-like protocol") action(l_queueMemoryWBRequest, "lq", desc="Write PUTX data to memory") { peek(unblockNetwork_in, ResponseMsg) { - queueMemoryWrite(in_msg.Sender, address, to_memory_controller_latency, - in_msg.DataBlk); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := in_msg.Sender; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Len := 0; + } } } action(ld_queueMemoryDmaWrite, "ld", desc="Write DMA data to memory") { assert(is_valid(tbe)); - queueMemoryWritePartial(tbe.DmaRequestor, tbe.PhysicalAddress, - to_memory_controller_latency, tbe.DmaDataBlk, - tbe.Len); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := tbe.PhysicalAddress; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := tbe.DmaRequestor; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := tbe.DmaDataBlk; + out_msg.Len := tbe.Len; + } } action(ly_queueMemoryWriteFromTBE, "ly", desc="Write data to memory from TBE") { - queueMemoryWrite(machineID, address, to_memory_controller_latency, - tbe.DataBlk); + enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) { + out_msg.addr := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := tbe.DmaRequestor; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + out_msg.DataBlk := tbe.DataBlk; + out_msg.Len := 0; + } } action(ll_checkIncomingWriteback, "\l", desc="Check PUTX/PUTO response message") { diff --git a/src/mem/ruby/protocol/RubySlicc_Defines.sm b/src/mem/ruby/protocol/RubySlicc_Defines.sm index eb235f8f3..6ae3a6cb1 100644 --- a/src/mem/ruby/protocol/RubySlicc_Defines.sm +++ b/src/mem/ruby/protocol/RubySlicc_Defines.sm @@ -32,15 +32,6 @@ MachineID machineID; NodeID clusterID; Cycles recycle_latency; -// Functions implemented in the AbstractController class for -// making timing access to the memory maintained by the -// memory controllers. -void queueMemoryRead(MachineID id, Addr addr, Cycles latency); -void queueMemoryWrite(MachineID id, Addr addr, Cycles latency, - DataBlock block); -void queueMemoryWritePartial(MachineID id, Addr addr, Cycles latency, - DataBlock block, int size); - // Functions implemented in the AbstractController class for // making functional access to the memory maintained by the // memory controllers. diff --git a/src/mem/ruby/protocol/RubySlicc_MemControl.sm b/src/mem/ruby/protocol/RubySlicc_MemControl.sm index f211789be..801a7bb75 100644 --- a/src/mem/ruby/protocol/RubySlicc_MemControl.sm +++ b/src/mem/ruby/protocol/RubySlicc_MemControl.sm @@ -57,6 +57,7 @@ structure(MemoryMsg, desc="...", interface="Message") { MachineID OriginalRequestorMachId, desc="What component originally requested"; DataBlock DataBlk, desc="Data to writeback"; MessageSizeType MessageSize, desc="size category of the message"; + int Len, desc="size of the memory/dma request"; // Not all fields used by all protocols: PrefetchBit Prefetch, desc="Is this a prefetch request"; bool ReadX, desc="Exclusive"; diff --git a/src/mem/ruby/slicc_interface/AbstractController.cc b/src/mem/ruby/slicc_interface/AbstractController.cc index cc1ac26ec..59611ae10 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.cc +++ b/src/mem/ruby/slicc_interface/AbstractController.cc @@ -76,6 +76,10 @@ AbstractController::init() m_delayVCHistogram.push_back(new Stats::Histogram()); m_delayVCHistogram[i]->init(10); } + + if (getMemReqQueue()) { + getMemReqQueue()->setConsumer(this); + } } void @@ -202,6 +206,61 @@ AbstractController::wakeUpAllBuffers() } } +bool +AbstractController::serviceMemoryQueue() +{ + auto mem_queue = getMemReqQueue(); + assert(mem_queue); + if (!mem_queue->isReady(clockEdge())) { + return false; + } + + const MemoryMsg *mem_msg = (const MemoryMsg*)mem_queue->peek(); + unsigned int req_size = RubySystem::getBlockSizeBytes(); + if (mem_msg->m_Len > 0) { + req_size = mem_msg->m_Len; + } + + RequestPtr req + = std::make_shared(mem_msg->m_addr, req_size, 0, m_masterId); + PacketPtr pkt; + if (mem_msg->getType() == MemoryRequestType_MEMORY_WB) { + pkt = Packet::createWrite(req); + pkt->allocate(); + pkt->setData(mem_msg->m_DataBlk.getData(getOffset(mem_msg->m_addr), + req_size)); + } else if (mem_msg->getType() == MemoryRequestType_MEMORY_READ) { + pkt = Packet::createRead(req); + uint8_t *newData = new uint8_t[req_size]; + pkt->dataDynamic(newData); + } else { + panic("Unknown memory request type (%s) for addr %p", + MemoryRequestType_to_string(mem_msg->getType()), + mem_msg->m_addr); + } + + SenderState *s = new SenderState(mem_msg->m_Sender); + pkt->pushSenderState(s); + + if (RubySystem::getWarmupEnabled()) { + // Use functional rather than timing accesses during warmup + mem_queue->dequeue(clockEdge()); + memoryPort.sendFunctional(pkt); + // Since the queue was popped the controller may be able + // to make more progress. Make sure it wakes up + scheduleEvent(Cycles(1)); + recvTimingResp(pkt); + } else { + mem_queue->dequeue(clockEdge()); + memoryPort.schedTimingReq(pkt, clockEdge()); + // Since the queue was popped the controller may be able + // to make more progress. Make sure it wakes up + scheduleEvent(Cycles(1)); + } + + return true; +} + void AbstractController::blockOnQueue(Addr addr, MessageBuffer* port) { @@ -236,73 +295,6 @@ AbstractController::getPort(const std::string &if_name, PortID idx) return memoryPort; } -void -AbstractController::queueMemoryRead(const MachineID &id, Addr addr, - Cycles latency) -{ - RequestPtr req = std::make_shared( - 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( - 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(addr, size, 0, m_masterId); - - PacketPtr pkt = Packet::createWrite(req); - pkt->allocate(); - pkt->setData(block.getData(getOffset(addr), size)); - - SenderState *s = new SenderState(id); - pkt->pushSenderState(s); - - // Create a block and copy data from the block. - memoryPort.schedTimingReq(pkt, clockEdge(latency)); -} - void AbstractController::functionalMemoryRead(PacketPtr pkt) { @@ -327,7 +319,7 @@ AbstractController::functionalMemoryWrite(PacketPtr pkt) void AbstractController::recvTimingResp(PacketPtr pkt) { - assert(getMemoryQueue()); + assert(getMemRespQueue()); assert(pkt->isResponse()); std::shared_ptr msg = std::make_shared(clockEdge()); @@ -352,7 +344,7 @@ AbstractController::recvTimingResp(PacketPtr pkt) panic("Incorrect packet type received from memory controller!"); } - getMemoryQueue()->enqueue(msg, clockEdge(), cyclesToTicks(Cycles(1))); + getMemRespQueue()->enqueue(msg, clockEdge(), cyclesToTicks(Cycles(1))); delete pkt; } diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh b/src/mem/ruby/slicc_interface/AbstractController.hh index 2007026e7..1c34bdef4 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.hh +++ b/src/mem/ruby/slicc_interface/AbstractController.hh @@ -90,7 +90,8 @@ class AbstractController : public ClockedObject, public Consumer bool isBlocked(Addr); virtual MessageBuffer* getMandatoryQueue() const = 0; - virtual MessageBuffer* getMemoryQueue() const = 0; + virtual MessageBuffer* getMemReqQueue() const = 0; + virtual MessageBuffer* getMemRespQueue() const = 0; virtual AccessPermission getAccessPermission(const Addr &addr) = 0; virtual void print(std::ostream & out) const = 0; @@ -136,11 +137,6 @@ class AbstractController : public ClockedObject, public Consumer Port &getPort(const std::string &if_name, PortID idx=InvalidPortID); - void queueMemoryRead(const MachineID &id, Addr addr, Cycles latency); - void queueMemoryWrite(const MachineID &id, Addr addr, Cycles latency, - const DataBlock &block); - void queueMemoryWritePartial(const MachineID &id, Addr addr, Cycles latency, - const DataBlock &block, int size); void recvTimingResp(PacketPtr pkt); Tick recvAtomic(PacketPtr pkt); @@ -178,6 +174,7 @@ class AbstractController : public ClockedObject, public Consumer void wakeUpBuffers(Addr addr); void wakeUpAllBuffers(Addr addr); void wakeUpAllBuffers(); + bool serviceMemoryQueue(); protected: const NodeID m_version; diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py index 65a906243..0e336e676 100644 --- a/src/mem/slicc/symbols/StateMachine.py +++ b/src/mem/slicc/symbols/StateMachine.py @@ -299,7 +299,8 @@ class $c_ident : public AbstractController void init(); MessageBuffer *getMandatoryQueue() const; - MessageBuffer *getMemoryQueue() const; + MessageBuffer *getMemReqQueue() const; + MessageBuffer *getMemRespQueue() const; void initNetQueues(); void print(std::ostream& out) const; @@ -672,6 +673,11 @@ $c_ident::init() if port.code.find("mandatoryQueue_ptr") >= 0: mq_ident = "m_mandatoryQueue_ptr" + memoutq_ident = "NULL" + for param in self.config_parameters: + if param.ident.find("requestToMemory") >= 0: + memoutq_ident = "m_requestToMemory_ptr" + memq_ident = "NULL" for port in self.in_ports: if port.code.find("responseFromMemory_ptr") >= 0: @@ -854,7 +860,13 @@ $c_ident::getMandatoryQueue() const } MessageBuffer* -$c_ident::getMemoryQueue() const +$c_ident::getMemReqQueue() const +{ + return $memoutq_ident; +} + +MessageBuffer* +$c_ident::getMemRespQueue() const { return $memq_ident; } @@ -1085,6 +1097,10 @@ using namespace std; void ${ident}_Controller::wakeup() { + if (getMemReqQueue() && getMemReqQueue()->isReady(clockEdge())) { + serviceMemoryQueue(); + } + int counter = 0; while (true) { unsigned char rejected[${{len(msg_bufs)}}]; -- 2.30.2