ruby: interface with classic memory controller
authorNilay Vaish <nilay@cs.wisc.edu>
Thu, 6 Nov 2014 11:42:21 +0000 (05:42 -0600)
committerNilay Vaish <nilay@cs.wisc.edu>
Thu, 6 Nov 2014 11:42:21 +0000 (05:42 -0600)
This patch is the final in the series.  The whole series and this patch in
particular were written with the aim of interfacing ruby's directory controller
with the memory controller in the classic memory system.  This is being done
since ruby's memory controller has not being kept up to date with the changes
going on in DRAMs.  Classic's memory controller is more up to date and
supports multiple different types of DRAM.  This also brings classic and
ruby ever more close.  The patch also changes ruby's memory controller to
expose the same interface.

48 files changed:
configs/common/MemConfig.py
configs/example/fs.py
configs/example/ruby_direct_test.py
configs/example/ruby_mem_test.py
configs/example/ruby_random_test.py
configs/example/se.py
configs/ruby/MESI_Three_Level.py
configs/ruby/MESI_Two_Level.py
configs/ruby/MI_example.py
configs/ruby/MOESI_CMP_directory.py
configs/ruby/MOESI_CMP_token.py
configs/ruby/MOESI_hammer.py
configs/ruby/Ruby.py
src/mem/protocol/MESI_Two_Level-dir.sm
src/mem/protocol/MI_example-dir.sm
src/mem/protocol/MOESI_CMP_directory-dir.sm
src/mem/protocol/MOESI_CMP_token-dir.sm
src/mem/protocol/MOESI_hammer-dir.sm
src/mem/protocol/RubySlicc_Defines.sm
src/mem/protocol/RubySlicc_Types.sm
src/mem/ruby/SConscript
src/mem/ruby/network/MessageBuffer.cc
src/mem/ruby/slicc_interface/AbstractController.cc
src/mem/ruby/slicc_interface/AbstractController.hh
src/mem/ruby/slicc_interface/Controller.py
src/mem/ruby/structures/Cache.py
src/mem/ruby/structures/DirectoryMemory.py
src/mem/ruby/structures/MemoryControl.cc [deleted file]
src/mem/ruby/structures/MemoryControl.hh [deleted file]
src/mem/ruby/structures/MemoryControl.py [deleted file]
src/mem/ruby/structures/MemoryNode.cc
src/mem/ruby/structures/MemoryNode.hh
src/mem/ruby/structures/MemoryVector.hh [deleted file]
src/mem/ruby/structures/RubyMemoryControl.cc
src/mem/ruby/structures/RubyMemoryControl.hh
src/mem/ruby/structures/RubyMemoryControl.py
src/mem/ruby/structures/SConscript
src/mem/ruby/system/RubySystem.py
src/mem/ruby/system/Sequencer.py
src/mem/ruby/system/System.cc
src/mem/ruby/system/System.hh
src/mem/slicc/symbols/StateMachine.py
src/python/swig/pyobject.cc
tests/configs/memtest-ruby.py
tests/configs/pc-simple-timing-ruby.py
tests/configs/rubytest-ruby.py
tests/configs/simple-timing-mp-ruby.py
tests/configs/simple-timing-ruby.py

index d203118aa0cbdb13cb3236619b6d397bf7584d52..57066426f3b05b5e3c9aa101f7ecb50cb0011b99 100644 (file)
@@ -54,7 +54,8 @@ _mem_aliases_all = [
     ("lpddr2_s4_1066_x32", "LPDDR2_S4_1066_x32"),
     ("lpddr3_1600_x32", "LPDDR3_1600_x32"),
     ("wio_200_x128", "WideIO_200_x128"),
-    ("dramsim2", "DRAMSim2")
+    ("dramsim2", "DRAMSim2"),
+    ("ruby_memory", "RubyMemoryControl")
     ]
 
 # Filtered list of aliases. Only aliases for existing memory
index abf8fe9667f5440b1779e397c32f20089ef15308..727f69339608829e35d8172da1af1069de988bbb 100644 (file)
@@ -137,8 +137,6 @@ def build_test_system(np):
 
         Ruby.create_system(options, True, test_sys, test_sys.iobus,
                            test_sys._dma_ports)
-        test_sys.physmem = [SimpleMemory(range = r, null = True)
-                          for r in test_sys.mem_ranges]
 
         # Create a seperate clock domain for Ruby
         test_sys.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock,
index 6773aea6d834ad975fc5874a36b70d32e3c26302..857909ba92cbc33f1169670bca22a99f1b381582 100644 (file)
@@ -48,7 +48,7 @@ m5_root = os.path.dirname(config_root)
 parser = optparse.OptionParser()
 Options.addCommonOptions(parser)
 
-parser.add_option("-l", "--requests", metavar="N", default=100,
+parser.add_option("--requests", metavar="N", default=100,
                   help="Stop after N requests")
 parser.add_option("-f", "--wakeup_freq", metavar="N", default=10,
                   help="Wakeup every N cycles")
@@ -87,13 +87,8 @@ else:
     print "Error: unknown direct test generator"
     sys.exit(1)
 
-#
-# Create the M5 system.  Note that the Memory Object isn't
-# actually used by the rubytester, but is included to support the
-# M5 memory size == Ruby memory size checks
-#
-system = System(physmem = SimpleMemory(),
-                mem_ranges = [AddrRange(options.mem_size)])
+# Create the M5 system.
+system = System(mem_ranges = [AddrRange(options.mem_size)])
 
 
 # Create a top-level voltage domain and clock domain
@@ -102,12 +97,9 @@ system.voltage_domain = VoltageDomain(voltage = options.sys_voltage)
 system.clk_domain = SrcClockDomain(clock = options.sys_clock,
                                    voltage_domain = system.voltage_domain)
 
-#
 # Create the ruby random tester
-#
-system.cpu = RubyDirectedTester(requests_to_complete = \
-                                   options.requests,
-                                   generator = generator)
+system.cpu = RubyDirectedTester(requests_to_complete = options.requests,
+                                generator = generator)
 
 Ruby.create_system(options, False, system)
 
@@ -121,7 +113,7 @@ for ruby_port in system.ruby._cpu_ports:
     #
     # Tie the ruby tester ports to the ruby cpu ports
     #
-    system.tester.cpuPort = ruby_port.slave
+    system.cpu.cpuPort = ruby_port.slave
 
 # -----------------------
 # run simulation
index 15684d153462d34f34e95580d23e9b29f6b0540a..f5e6d2a8240cee6360564191ccc8f2e4e5ad556e 100644 (file)
@@ -107,7 +107,6 @@ cpus = [ MemTest(atomic = False,
 system = System(cpu = cpus,
                 funcmem = SimpleMemory(in_addr_map = False),
                 funcbus = NoncoherentXBar(),
-                physmem = SimpleMemory(),
                 clk_domain = SrcClockDomain(clock = options.sys_clock),
                 mem_ranges = [AddrRange(options.mem_size)])
 
index 7cde5b86c195bef4849d1585ed8788e7a9366233..225b3d23bc4495562dc7e29ad05c680baf3553e7 100644 (file)
@@ -97,8 +97,7 @@ tester = RubyTester(check_flush = check_flush,
 # actually used by the rubytester, but is included to support the
 # M5 memory size == Ruby memory size checks
 #
-system = System(cpu = tester, physmem = SimpleMemory(),
-                mem_ranges = [AddrRange(options.mem_size)])
+system = System(cpu = tester, mem_ranges = [AddrRange(options.mem_size)])
 
 # Create a top-level voltage domain and clock domain
 system.voltage_domain = VoltageDomain(voltage = options.sys_voltage)
index 461ebf11c6ab6be2e15343cbf89e9fb6370c0c02..e0535c7269c2e1b3337cddfb33418e6c5d55fdb1 100644 (file)
@@ -225,11 +225,6 @@ if options.ruby:
         print >> sys.stderr, "Ruby requires TimingSimpleCPU or O3CPU!!"
         sys.exit(1)
 
-    # Use SimpleMemory with the null option since this memory is only used
-    # for determining which addresses are within the range of the memory.
-    # No space allocation is required.
-    system.physmem = SimpleMemory(range=AddrRange(options.mem_size),
-                              null = True)
     options.use_map = True
     Ruby.create_system(options, False, system)
     assert(options.num_cpus == len(system.ruby._cpu_ports))
index fe2e6aef5d51b801d4e24931ef1a9f51883f5d9a..f9ded25f19a9f4904dca513b28f4596d06771cc0 100644 (file)
@@ -182,22 +182,12 @@ def create_system(options, full_system, system, dma_ports, ruby_system):
         #
         # Create the Ruby objects associated with the directory controller
         #
-
-        mem_cntrl = RubyMemoryControl(
-                              clk_domain = ruby_system.memctrl_clk_domain,
-                              version = i,
-                              ruby_system = ruby_system)
-
         dir_size = MemorySize('0B')
         dir_size.value = mem_module_size
 
         dir_cntrl = Directory_Controller(version = i,
-                                         directory = \
-                                         RubyDirectoryMemory(version = i,
-                                                             size = dir_size,
-                                                             use_map =
-                                                           options.use_map),
-                                         memBuffer = mem_cntrl,
+                                         directory = RubyDirectoryMemory(
+                                             version = i, size = dir_size),
                                          transitions_per_cycle = options.ports,
                                          ruby_system = ruby_system)
 
index 6cc4efcb9e43ad20d3791a949c2a242cff3516bf..b7bdd144706d437b578170202dbd7c0415068625 100644 (file)
@@ -162,25 +162,12 @@ def create_system(options, full_system, system, dma_ports, ruby_system):
                                           clk_divider=3)
 
     for i in xrange(options.num_dirs):
-        #
-        # Create the Ruby objects associated with the directory controller
-        #
-
-        mem_cntrl = RubyMemoryControl(
-                              clk_domain = ruby_system.memctrl_clk_domain,
-                              version = i,
-                              ruby_system = ruby_system)
-
         dir_size = MemorySize('0B')
         dir_size.value = mem_module_size
 
         dir_cntrl = Directory_Controller(version = i,
-                                         directory = \
-                                         RubyDirectoryMemory(version = i,
-                                                             size = dir_size,
-                                                             use_map =
-                                                           options.use_map),
-                                         memBuffer = mem_cntrl,
+                                         directory = RubyDirectoryMemory(
+                                             version = i, size = dir_size),
                                          transitions_per_cycle = options.ports,
                                          ruby_system = ruby_system)
 
index de1f3e9241fd3de4b018e684655bd81ac59afc4b..2dd064b55149669395c14522fedf21be25c1667c 100644 (file)
@@ -117,27 +117,11 @@ def create_system(options, full_system, system, dma_ports, ruby_system):
                                           clk_divider=3)
 
     for i in xrange(options.num_dirs):
-        #
-        # Create the Ruby objects associated with the directory controller
-        #
-
-        mem_cntrl = RubyMemoryControl(
-                              clk_domain = ruby_system.memctrl_clk_domain,
-                              version = i,
-                              ruby_system = ruby_system)
-
         dir_size = MemorySize('0B')
         dir_size.value = mem_module_size
-
         dir_cntrl = Directory_Controller(version = i,
-                                         directory = \
-                                         RubyDirectoryMemory( \
-                                                    version = i,
-                                                    size = dir_size,
-                                                    use_map = options.use_map,
-                                                    map_levels = \
-                                                      options.map_levels),
-                                         memBuffer = mem_cntrl,
+                                         directory = RubyDirectoryMemory(
+                                             version = i, size = dir_size),
                                          transitions_per_cycle = options.ports,
                                          ruby_system = ruby_system)
 
index 3fb9c55a7d0777f78fe814c1aaed809116fad59f..9c4bab4343b9899ea77e7ab58eceb4f5709aa757 100644 (file)
@@ -156,24 +156,12 @@ def create_system(options, full_system, system, dma_ports, ruby_system):
                                           clk_divider=3)
 
     for i in xrange(options.num_dirs):
-        #
-        # Create the Ruby objects associated with the directory controller
-        #
-
-        mem_cntrl = RubyMemoryControl(
-                              clk_domain = ruby_system.memctrl_clk_domain,
-                              version = i,
-                              ruby_system = ruby_system)
-
         dir_size = MemorySize('0B')
         dir_size.value = mem_module_size
 
         dir_cntrl = Directory_Controller(version = i,
-                                         directory = \
-                                         RubyDirectoryMemory(version = i,
-                                             size = dir_size,
-                                             use_map = options.use_map),
-                                         memBuffer = mem_cntrl,
+                                         directory = RubyDirectoryMemory(
+                                             version = i, size = dir_size),
                                          transitions_per_cycle = options.ports,
                                          ruby_system = ruby_system)
 
index bedc444bff11366b353c189c259559d3cf89264e..26cd625b59114f82114439a71bf1a114f2afa473 100644 (file)
@@ -180,24 +180,12 @@ def create_system(options, full_system, system, dma_ports, ruby_system):
                                           clk_divider=3)
 
     for i in xrange(options.num_dirs):
-        #
-        # Create the Ruby objects associated with the directory controller
-        #
-
-        mem_cntrl = RubyMemoryControl(
-                              clk_domain = ruby_system.memctrl_clk_domain,
-                              version = i,
-                              ruby_system = ruby_system)
-
         dir_size = MemorySize('0B')
         dir_size.value = mem_module_size
 
         dir_cntrl = Directory_Controller(version = i,
-                                         directory = \
-                                         RubyDirectoryMemory(version = i,
-                                             use_map = options.use_map,
-                                             size = dir_size),
-                                         memBuffer = mem_cntrl,
+                                         directory = RubyDirectoryMemory(
+                                             version = i, size = dir_size),
                                          l2_select_num_bits = l2_bits,
                                          transitions_per_cycle = options.ports,
                                          ruby_system = ruby_system)
index 2f9aaebc78063369b5aa2a6e53c1724ff1d46ba2..740c6783e4935cbaeae07347483ccb883b84d677 100644 (file)
@@ -170,15 +170,6 @@ def create_system(options, full_system, system, dma_ports, ruby_system):
                                           clk_divider=3)
 
     for i in xrange(options.num_dirs):
-        #
-        # Create the Ruby objects associated with the directory controller
-        #
-
-        mem_cntrl = RubyMemoryControl(
-                              clk_domain = ruby_system.memctrl_clk_domain,
-                              version = i,
-                              ruby_system = ruby_system)
-
         dir_size = MemorySize('0B')
         dir_size.value = mem_module_size
 
@@ -186,17 +177,9 @@ def create_system(options, full_system, system, dma_ports, ruby_system):
                          start_index_bit = pf_start_bit)
 
         dir_cntrl = Directory_Controller(version = i,
-                                         directory = \
-                                         RubyDirectoryMemory( \
-                                                    version = i,
-                                                    size = dir_size,
-                                                    use_map = options.use_map,
-                                                    map_levels = \
-                                                    options.map_levels,
-                                                    numa_high_bit = \
-                                                      options.numa_high_bit),
+                                         directory = RubyDirectoryMemory(
+                                            version = i, size = dir_size),
                                          probeFilter = pf,
-                                         memBuffer = mem_cntrl,
                                          probe_filter_enabled = options.pf_on,
                                          full_bit_dir_enabled = options.dir_on,
                                          transitions_per_cycle = options.ports,
index b7fd5078b3834fe8171ea41c16feb82570658ea6..35ff66a0c5b4d3f7c09f0410d54d303f0065a2c4 100644 (file)
@@ -45,6 +45,7 @@ from m5.objects import *
 from m5.defines import buildEnv
 from m5.util import addToPath, fatal
 
+import MemConfig
 addToPath('../topologies')
 
 def define_options(parser):
@@ -75,22 +76,67 @@ def define_options(parser):
                       help="high order address bit to use for numa mapping. " \
                            "0 = highest bit, not specified = lowest bit")
 
-    # ruby sparse memory options
-    parser.add_option("--use-map", action="store_true", default=False)
-    parser.add_option("--map-levels", type="int", default=4)
-
     parser.add_option("--recycle-latency", type="int", default=10,
                       help="Recycle latency for ruby controller input buffers")
 
     parser.add_option("--random_seed", type="int", default=1234,
                       help="Used for seeding the random number generator")
 
-    parser.add_option("--ruby_stats", type="string", default="ruby.stats")
-
     protocol = buildEnv['PROTOCOL']
     exec "import %s" % protocol
     eval("%s.define_options(parser)" % protocol)
 
+def setup_memory_controllers(system, ruby, dir_cntrls, options):
+    ruby.block_size_bytes = options.cacheline_size
+    ruby.memory_size_bits = 48
+    block_size_bits = int(math.log(options.cacheline_size, 2))
+
+    if options.numa_high_bit:
+        numa_bit = options.numa_high_bit
+    else:
+        # if the numa_bit is not specified, set the directory bits as the
+        # lowest bits above the block offset bits, and the numa_bit as the
+        # highest of those directory bits
+        dir_bits = int(math.log(options.num_dirs, 2))
+        numa_bit = block_size_bits + dir_bits - 1
+
+    index = 0
+    mem_ctrls = []
+    crossbars = []
+
+    # Sets bits to be used for interleaving.  Creates memory controllers
+    # attached to a directory controller.  A separate controller is created
+    # for each address range as the abstract memory can handle only one
+    # contiguous address range as of now.
+    for dir_cntrl in dir_cntrls:
+        dir_cntrl.directory.numa_high_bit = numa_bit
+
+        crossbar = None
+        if len(system.mem_ranges) > 1:
+            crossbar = NoncoherentXBar()
+            crossbars.append(crossbar)
+            dir_cntrl.memory = crossbar.slave
+
+        for r in system.mem_ranges:
+            mem_ctrl = MemConfig.create_mem_ctrl(
+                MemConfig.get(options.mem_type), r, index, options.num_dirs,
+                int(math.log(options.num_dirs, 2)), options.cacheline_size)
+
+            mem_ctrls.append(mem_ctrl)
+
+            if crossbar != None:
+                mem_ctrl.port = crossbar.master
+            else:
+                mem_ctrl.port = dir_cntrl.memory
+
+        index += 1
+
+    system.mem_ctrls = mem_ctrls
+
+    if len(crossbars) > 0:
+        ruby.crossbars = crossbars
+
+
 def create_topology(controllers, options):
     """ Called from create_system in configs/ruby/<protocol>.py
         Must return an object which is a subclass of BaseTopology
@@ -103,7 +149,7 @@ def create_topology(controllers, options):
 
 def create_system(options, full_system, system, piobus = None, dma_ports = []):
 
-    system.ruby = RubySystem(no_mem_vec = options.use_map)
+    system.ruby = RubySystem()
     ruby = system.ruby
 
     # Set the network classes based on the command line options
@@ -169,33 +215,7 @@ def create_system(options, full_system, system, piobus = None, dma_ports = []):
         network.enable_fault_model = True
         network.fault_model = FaultModel()
 
-    # Loop through the directory controlers.
-    # Determine the total memory size of the ruby system and verify it is equal
-    # to physmem.  However, if Ruby memory is using sparse memory in SE
-    # mode, then the system should not back-up the memory state with
-    # the Memory Vector and thus the memory size bytes should stay at 0.
-    # Also set the numa bits to the appropriate values.
-    total_mem_size = MemorySize('0B')
-
-    ruby.block_size_bytes = options.cacheline_size
-    block_size_bits = int(math.log(options.cacheline_size, 2))
-
-    if options.numa_high_bit:
-        numa_bit = options.numa_high_bit
-    else:
-        # if the numa_bit is not specified, set the directory bits as the
-        # lowest bits above the block offset bits, and the numa_bit as the
-        # highest of those directory bits
-        dir_bits = int(math.log(options.num_dirs, 2))
-        numa_bit = block_size_bits + dir_bits - 1
-
-    for dir_cntrl in dir_cntrls:
-        total_mem_size.value += dir_cntrl.directory.size.value
-        dir_cntrl.directory.numa_high_bit = numa_bit
-
-    phys_mem_size = sum(map(lambda r: r.size(), system.mem_ranges))
-    assert(total_mem_size.value == phys_mem_size)
-    ruby.mem_size = total_mem_size
+    setup_memory_controllers(system, ruby, dir_cntrls, options)
 
     # Connect the cpu sequencers and the piobus
     if piobus != None:
index 939ae2a36a1256f15112e6b2b2e0481256d24900..fa9d1f3d3ca80376f92b72e8070c2c7e6b91377a 100644 (file)
@@ -28,7 +28,6 @@
 
 machine(Directory, "MESI Two Level directory protocol")
  : DirectoryMemory * directory;
-   MemoryControl * memBuffer;
    Cycles to_mem_ctrl_latency := 1;
    Cycles directory_latency := 6;
 
@@ -154,17 +153,21 @@ machine(Directory, "MESI Two Level directory protocol")
     if(is_valid(tbe)) {
       testAndRead(addr, tbe.DataBlk, pkt);
     } else {
-      memBuffer.functionalRead(pkt);
+      functionalMemoryRead(pkt);
     }
   }
 
   int functionalWrite(Address addr, Packet *pkt) {
+    int num_functional_writes := 0;
+
     TBE tbe := TBEs[addr];
     if(is_valid(tbe)) {
-      testAndWrite(addr, tbe.DataBlk, pkt);
+      num_functional_writes := num_functional_writes +
+        testAndWrite(addr, tbe.DataBlk, pkt);
     }
 
-    return memBuffer.functionalWrite(pkt);
+    num_functional_writes := num_functional_writes + functionalMemoryWrite(pkt);
+    return num_functional_writes;
   }
 
   void setAccessPermission(Address addr, State state) {
@@ -182,7 +185,6 @@ machine(Directory, "MESI Two Level directory protocol")
 
   // ** OUT_PORTS **
   out_port(responseNetwork_out, ResponseMsg, responseFromDir);
-  out_port(memQueue_out, MemoryMsg, memBuffer);
 
   // ** IN_PORTS **
 
@@ -223,7 +225,7 @@ machine(Directory, "MESI Two Level directory protocol")
   }
 
   // off-chip memory request/response is done
-  in_port(memQueue_in, MemoryMsg, memBuffer, rank = 2) {
+  in_port(memQueue_in, MemoryMsg, responseFromMemory, rank = 2) {
     if (memQueue_in.isReady()) {
       peek(memQueue_in, MemoryMsg) {
         if (in_msg.Type == MemoryRequestType:MEMORY_READ) {
@@ -300,46 +302,21 @@ machine(Directory, "MESI Two Level directory protocol")
 
   action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
     peek(requestNetwork_in, RequestMsg) {
-      enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) {
-        out_msg.Addr := address;
-        out_msg.Type := MemoryRequestType:MEMORY_READ;
-        out_msg.Sender := machineID;
-        out_msg.OriginalRequestorMachId := in_msg.Requestor;
-        out_msg.MessageSize := in_msg.MessageSize;
-        out_msg.Prefetch := in_msg.Prefetch;
-
-        DPRINTF(RubySlicc, "%s\n", out_msg);
-      }
+      queueMemoryRead(in_msg.Requestor, address, to_mem_ctrl_latency);
     }
   }
 
   action(qw_queueMemoryWBRequest, "qw", desc="Queue off-chip writeback request") {
     peek(responseNetwork_in, ResponseMsg) {
-      enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) {
-        out_msg.Addr := address;
-        out_msg.Type := MemoryRequestType:MEMORY_WB;
-        out_msg.Sender := machineID;
-        out_msg.OriginalRequestorMachId := in_msg.Sender;
-        out_msg.DataBlk := in_msg.DataBlk;
-        out_msg.MessageSize := in_msg.MessageSize;
-        //out_msg.Prefetch := in_msg.Prefetch;
-
-        DPRINTF(RubySlicc, "%s\n", out_msg);
-      }
+      queueMemoryWrite(in_msg.Sender, address, to_mem_ctrl_latency,
+                       in_msg.DataBlk);
     }
   }
 
 //added by SS for dma
   action(qf_queueMemoryFetchRequestDMA, "qfd", desc="Queue off-chip fetch request") {
     peek(requestNetwork_in, RequestMsg) {
-      enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) {
-        out_msg.Addr := address;
-        out_msg.Type := MemoryRequestType:MEMORY_READ;
-        out_msg.Sender := machineID;
-        out_msg.OriginalRequestorMachId := machineID;
-        out_msg.MessageSize := in_msg.MessageSize;
-        DPRINTF(RubySlicc, "%s\n", out_msg);
-      }
+      queueMemoryRead(in_msg.Requestor, address, to_mem_ctrl_latency);
     }
   }
 
@@ -359,16 +336,11 @@ machine(Directory, "MESI Two Level directory protocol")
     }
   }
 
-  action(qw_queueMemoryWBRequest_partial, "qwp", desc="Queue off-chip writeback request") {
-     peek(requestNetwork_in, RequestMsg) {
-      enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) {
-        out_msg.Addr := address;
-        out_msg.Type := MemoryRequestType:MEMORY_WB;
-        out_msg.OriginalRequestorMachId := machineID;
-        out_msg.DataBlk.copyPartial(in_msg.DataBlk, addressOffset(address), in_msg.Len);
-        out_msg.MessageSize := in_msg.MessageSize;
-        DPRINTF(RubySlicc, "%s\n", out_msg);
-      }
+  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);
     }
   }
 
@@ -424,22 +396,11 @@ machine(Directory, "MESI Two Level directory protocol")
     }
   }
 
-  action(qw_queueMemoryWBRequest_partialTBE, "qwt", desc="Queue off-chip writeback request") {
+  action(qw_queueMemoryWBRequest_partialTBE, "qwt",
+         desc="Queue off-chip writeback request") {
     peek(responseNetwork_in, ResponseMsg) {
-      enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) {
-        assert(is_valid(tbe));
-        out_msg.Addr := address;
-        out_msg.Type := MemoryRequestType:MEMORY_WB;
-        out_msg.OriginalRequestorMachId := in_msg.Sender;
-        //out_msg.DataBlk := in_msg.DataBlk;
-        //out_msg.DataBlk.copyPartial(tbe.DataBlk, tbe.Offset, tbe.Len);
-        out_msg.DataBlk.copyPartial(tbe.DataBlk, addressOffset(tbe.PhysicalAddress), tbe.Len);
-
-        out_msg.MessageSize := in_msg.MessageSize;
-        //out_msg.Prefetch := in_msg.Prefetch;
-
-        DPRINTF(RubySlicc, "%s\n", out_msg);
-      }
+      queueMemoryWritePartial(in_msg.Sender, tbe.PhysicalAddress,
+                              to_mem_ctrl_latency, tbe.DataBlk, tbe.Len);
     }
   }
 
index 60662080ae50ce3f88337b48e40ff5f01cf81501..def7053ea90316eeea788920060e7f7d3fac3e7a 100644 (file)
@@ -29,8 +29,8 @@
 
 machine(Directory, "Directory protocol") 
     : DirectoryMemory * directory;
-      MemoryControl * memBuffer;
       Cycles directory_latency := 12;
+      Cycles to_memory_controller_latency := 1;
 
       MessageBuffer * forwardFromDir, network="To", virtual_network="3",
             ordered="false", vnet_type="forward";
@@ -178,17 +178,21 @@ machine(Directory, "Directory protocol")
     if(is_valid(tbe)) {
       testAndRead(addr, tbe.DataBlk, pkt);
     } else {
-      memBuffer.functionalRead(pkt);
+      functionalMemoryRead(pkt);
     }
   }
 
   int functionalWrite(Address addr, Packet *pkt) {
+    int num_functional_writes := 0;
+
     TBE tbe := TBEs[addr];
     if(is_valid(tbe)) {
-      testAndWrite(addr, tbe.DataBlk, pkt);
+      num_functional_writes := num_functional_writes +
+            testAndWrite(addr, tbe.DataBlk, pkt);
     }
 
-    return memBuffer.functionalWrite(pkt);
+    num_functional_writes := num_functional_writes + functionalMemoryWrite(pkt);
+    return num_functional_writes;
   }
 
   // ** OUT_PORTS **
@@ -197,10 +201,7 @@ machine(Directory, "Directory protocol")
   out_port(requestQueue_out, ResponseMsg, requestToDir); // For recycling requests
   out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir);
 
-//added by SS
-  out_port(memQueue_out, MemoryMsg, memBuffer);
   // ** IN_PORTS **
-
   in_port(dmaRequestQueue_in, DMARequestMsg, dmaRequestToDir) {
     if (dmaRequestQueue_in.isReady()) {
       peek(dmaRequestQueue_in, DMARequestMsg) {
@@ -239,7 +240,7 @@ machine(Directory, "Directory protocol")
 
 //added by SS
   // off-chip memory request/response is done
-  in_port(memQueue_in, MemoryMsg, memBuffer) {
+  in_port(memQueue_in, MemoryMsg, responseFromMemory) {
     if (memQueue_in.isReady()) {
       peek(memQueue_in, MemoryMsg) {
         TBE tbe := TBEs[in_msg.Addr];
@@ -440,73 +441,36 @@ machine(Directory, "Directory protocol")
 
   action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
     peek(requestQueue_in, RequestMsg) {
-      enqueue(memQueue_out, MemoryMsg, 1) {
-        out_msg.Addr := address;
-        out_msg.Type := MemoryRequestType:MEMORY_READ;
-        out_msg.Sender := machineID;
-        out_msg.OriginalRequestorMachId := in_msg.Requestor;
-        out_msg.MessageSize := in_msg.MessageSize;
-        DPRINTF(RubySlicc,"%s\n", out_msg);
-      }
+      queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
     }
   }
 
   action(qf_queueMemoryFetchRequestDMA, "qfd", desc="Queue off-chip fetch request") {
     peek(dmaRequestQueue_in, DMARequestMsg) {
-      enqueue(memQueue_out, MemoryMsg, 1) {
-        out_msg.Addr := address;
-        out_msg.Type := MemoryRequestType:MEMORY_READ;
-        out_msg.Sender := machineID;
-        //out_msg.OriginalRequestorMachId := machineID;
-        out_msg.MessageSize := in_msg.MessageSize;
-        DPRINTF(RubySlicc,"%s\n", out_msg);
-      }
+      queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
     }
   }
 
   action(qw_queueMemoryWBRequest_partial, "qwp", desc="Queue off-chip writeback request") {
-     peek(dmaRequestQueue_in, DMARequestMsg) {
-      enqueue(memQueue_out, MemoryMsg, 1) {
-        out_msg.Addr := address;
-        out_msg.Type := MemoryRequestType:MEMORY_WB;
-        out_msg.DataBlk.copyPartial(
-            in_msg.DataBlk, addressOffset(in_msg.PhysicalAddress), in_msg.Len);
-        out_msg.MessageSize := in_msg.MessageSize;
-        DPRINTF(RubySlicc,"%s\n", out_msg);
-      }
+    peek(dmaRequestQueue_in, DMARequestMsg) {
+      queueMemoryWritePartial(in_msg.Requestor, address,
+                              to_memory_controller_latency, in_msg.DataBlk,
+                              in_msg.Len);
     }
   }
 
   action(qw_queueMemoryWBRequest_partialTBE, "qwt", desc="Queue off-chip writeback request") {
     peek(requestQueue_in, RequestMsg) {
-      enqueue(memQueue_out, MemoryMsg, 1) {
-        assert(is_valid(tbe));
-        out_msg.Addr := address;
-        out_msg.Type := MemoryRequestType:MEMORY_WB;
-        out_msg.OriginalRequestorMachId := in_msg.Requestor;
-
-        // get incoming data
-        out_msg.DataBlk.copyPartial(
-            tbe.DataBlk, addressOffset(tbe.PhysicalAddress), tbe.Len);
-        out_msg.MessageSize := in_msg.MessageSize;
-        DPRINTF(RubySlicc,"%s\n", out_msg);
-      }
+      queueMemoryWritePartial(in_msg.Requestor, address,
+                              to_memory_controller_latency, tbe.DataBlk,
+                              tbe.Len);
     }
   }
 
-
   action(l_queueMemoryWBRequest, "lq", desc="Write PUTX data to memory") {
     peek(requestQueue_in, RequestMsg) {
-      enqueue(memQueue_out, MemoryMsg, 1) {
-        out_msg.Addr := address;
-        out_msg.Type := MemoryRequestType:MEMORY_WB;
-        out_msg.Sender := machineID;
-        out_msg.OriginalRequestorMachId := in_msg.Requestor;
-        out_msg.DataBlk := in_msg.DataBlk;
-        out_msg.MessageSize := in_msg.MessageSize;
-
-        DPRINTF(RubySlicc,"%s\n", out_msg);
-      }
+      queueMemoryWrite(in_msg.Requestor, address, to_memory_controller_latency,
+                       in_msg.DataBlk);
     }
   }
 
index a6b93fa549983944bf3984c1eccc2ef044e87fdb..3e19897f352e7d3bd9c2c0181a09b9c9ec77d907 100644 (file)
@@ -28,8 +28,8 @@
 
 machine(Directory, "Directory protocol")
 :  DirectoryMemory * directory;
-   MemoryControl * memBuffer;
    Cycles directory_latency := 6;
+   Cycles to_memory_controller_latency := 1;
 
    // Message Queues
    MessageBuffer * requestToDir, network="From", virtual_network="1",
@@ -191,11 +191,13 @@ machine(Directory, "Directory protocol")
   }
 
   void functionalRead(Address addr, Packet *pkt) {
-    memBuffer.functionalRead(pkt);
+    functionalMemoryRead(pkt);
   }
 
   int functionalWrite(Address addr, Packet *pkt) {
-    return memBuffer.functionalWrite(pkt);
+    int num_functional_writes := 0;
+    num_functional_writes := num_functional_writes + functionalMemoryWrite(pkt);
+    return num_functional_writes;
   }
 
   // if no sharers, then directory can be considered
@@ -222,7 +224,6 @@ machine(Directory, "Directory protocol")
   // ** OUT_PORTS **
   out_port(forwardNetwork_out, RequestMsg, forwardFromDir);
   out_port(responseNetwork_out, ResponseMsg, responseFromDir);
-  out_port(memQueue_out, MemoryMsg, memBuffer);
 
   // ** IN_PORTS **
 
@@ -286,7 +287,7 @@ machine(Directory, "Directory protocol")
   }
 
   // off-chip memory request/response is done
-  in_port(memQueue_in, MemoryMsg, memBuffer) {
+  in_port(memQueue_in, MemoryMsg, responseFromMemory) {
     if (memQueue_in.isReady()) {
       peek(memQueue_in, MemoryMsg) {
         if (in_msg.Type == MemoryRequestType:MEMORY_READ) {
@@ -465,41 +466,18 @@ machine(Directory, "Directory protocol")
 
   action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
     peek(requestQueue_in, RequestMsg) {
-      enqueue(memQueue_out, MemoryMsg, 1) {
-        out_msg.Addr := address;
-        out_msg.Type := MemoryRequestType:MEMORY_READ;
-        out_msg.Sender := machineID;
-        out_msg.OriginalRequestorMachId := in_msg.Requestor;
-        out_msg.MessageSize := in_msg.MessageSize;
-        //out_msg.Prefetch := false;
-        // These are not used by memory but are passed back here with the read data:
-        out_msg.ReadX := (in_msg.Type == CoherenceRequestType:GETS &&
-                          getDirectoryEntry(address).Sharers.count() == 0);
-        out_msg.Acks := getDirectoryEntry(address).Sharers.count();
-        if (getDirectoryEntry(address).Sharers.isElement(in_msg.Requestor)) {
-          out_msg.Acks := out_msg.Acks - 1;
-        }
-        DPRINTF(RubySlicc, "%s\n", out_msg);
-      }
+      queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
     }
   }
 
   action(qw_queueMemoryWBRequest, "qw", desc="Queue off-chip writeback request") {
     peek(unblockNetwork_in, ResponseMsg) {
-      enqueue(memQueue_out, MemoryMsg, 1) {
-        out_msg.Addr := address;
-        out_msg.Type := MemoryRequestType:MEMORY_WB;
-        out_msg.Sender := machineID;
-        if (is_valid(tbe)) {
-          out_msg.OriginalRequestorMachId := tbe.Requestor;
-        }
-        out_msg.DataBlk := in_msg.DataBlk;
-        out_msg.MessageSize := in_msg.MessageSize;
-        //out_msg.Prefetch := false;
-        // Not used:
-        out_msg.ReadX := false;
-        out_msg.Acks := getDirectoryEntry(address).Sharers.count();  // for dma requests
-        DPRINTF(RubySlicc, "%s\n", out_msg);
+      if (is_valid(tbe)) {
+        queueMemoryWrite(tbe.Requestor, address, to_memory_controller_latency,
+                         in_msg.DataBlk);
+      } else {
+        queueMemoryWrite(in_msg.Sender, address, to_memory_controller_latency,
+                         in_msg.DataBlk);
       }
     }
   }
@@ -507,41 +485,18 @@ machine(Directory, "Directory protocol")
   action(qw_queueMemoryWBRequestFromMessageAndTBE, "qwmt",
     desc="Queue off-chip writeback request") {
     peek(unblockNetwork_in, ResponseMsg) {
-      enqueue(memQueue_out, MemoryMsg, 1) {
-        out_msg.Addr := address;
-        out_msg.Type := MemoryRequestType:MEMORY_WB;
-        out_msg.Sender := machineID;
-        if (is_valid(tbe)) {
-          out_msg.OriginalRequestorMachId := tbe.Requestor;
-        }
-        out_msg.DataBlk := in_msg.DataBlk;
-        out_msg.DataBlk.copyPartial(tbe.DataBlk,
-            addressOffset(tbe.PhysicalAddress), tbe.Len);
-
-        out_msg.MessageSize := in_msg.MessageSize;
-        // Not used:
-        out_msg.ReadX := false;
-        out_msg.Acks := getDirectoryEntry(address).Sharers.count();  // for dma requests
-        DPRINTF(RubySlicc, "%s\n", out_msg);
-      }
+      DataBlock DataBlk := in_msg.DataBlk;
+      DataBlk.copyPartial(tbe.DataBlk, addressOffset(tbe.PhysicalAddress),
+                          tbe.Len);
+      queueMemoryWrite(tbe.Requestor, address, to_memory_controller_latency,
+                       DataBlk);
     }
   }
 
   action(qw_queueMemoryWBRequest2, "/qw", desc="Queue off-chip writeback request") {
     peek(requestQueue_in, RequestMsg) {
-      enqueue(memQueue_out, MemoryMsg, 1) {
-        out_msg.Addr := address;
-        out_msg.Type := MemoryRequestType:MEMORY_WB;
-        out_msg.Sender := machineID;
-        out_msg.OriginalRequestorMachId := in_msg.Requestor;
-        out_msg.DataBlk := in_msg.DataBlk;
-        out_msg.MessageSize := in_msg.MessageSize;
-        //out_msg.Prefetch := false;
-        // Not used:
-        out_msg.ReadX := false;
-        out_msg.Acks := getDirectoryEntry(address).Sharers.count();  // for dma requests
-        DPRINTF(RubySlicc, "%s\n", out_msg);
-      }
+      queueMemoryWrite(in_msg.Requestor, address, to_memory_controller_latency,
+                       in_msg.DataBlk);
     }
   }
 
index 8d6abd93c03dddb80dcbc513c7b2d56dd75dd713..a70ef60739441c2d6ebcf3c1d57cc26695bc4f03 100644 (file)
 
 machine(Directory, "Token protocol")
  : DirectoryMemory * directory;
-   MemoryControl * memBuffer;
    int l2_select_num_bits;
    Cycles directory_latency := 5;
    bool distributed_persistent := "True";
    Cycles fixed_timeout_latency := 100;
    Cycles reissue_wakeup_latency := 10;
+   Cycles to_memory_controller_latency := 1;
 
    // Message Queues from dir to other controllers / network
    MessageBuffer * dmaResponseFromDir, network="To", virtual_network="5",
@@ -148,8 +148,7 @@ machine(Directory, "Token protocol")
   structure(TBE, desc="TBE entries for outstanding DMA requests") {
     Address PhysicalAddress, desc="physical address";
     State TBEState,        desc="Transient State";
-    DataBlock DmaDataBlk,  desc="DMA Data to be written.  Partial blocks need to merged with system memory";
-    DataBlock DataBlk,     desc="The current view of system memory";
+    DataBlock DataBlk,     desc="Current view of the associated address range";
     int Len,               desc="...";
     MachineID DmaRequestor, desc="DMA requestor";
     bool WentPersistent,   desc="Did the DMA request require a persistent request";
@@ -250,17 +249,21 @@ machine(Directory, "Token protocol")
     if(is_valid(tbe)) {
       testAndRead(addr, tbe.DataBlk, pkt);
     } else {
-      memBuffer.functionalRead(pkt);
+      functionalMemoryRead(pkt);
     }
   }
 
   int functionalWrite(Address addr, Packet *pkt) {
+    int num_functional_writes := 0;
+
     TBE tbe := TBEs[addr];
     if(is_valid(tbe)) {
-      testAndWrite(addr, tbe.DataBlk, pkt);
+      num_functional_writes := num_functional_writes +
+            testAndWrite(addr, tbe.DataBlk, pkt);
     }
 
-    return memBuffer.functionalWrite(pkt);
+    num_functional_writes := num_functional_writes + functionalMemoryWrite(pkt);
+    return num_functional_writes;
   }
 
   // ** OUT_PORTS **
@@ -269,15 +272,9 @@ machine(Directory, "Token protocol")
   out_port(requestNetwork_out, RequestMsg, requestFromDir);
   out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir);
 
-  //
-  // Memory buffer for memory controller to DIMM communication
-  //
-  out_port(memQueue_out, MemoryMsg, memBuffer);
-
   // ** IN_PORTS **
-
   // off-chip memory request/response is done
-  in_port(memQueue_in, MemoryMsg, memBuffer) {
+  in_port(memQueue_in, MemoryMsg, responseFromMemory) {
     if (memQueue_in.isReady()) {
       peek(memQueue_in, MemoryMsg) {
         if (in_msg.Type == MemoryRequestType:MEMORY_READ) {
@@ -653,73 +650,39 @@ machine(Directory, "Token protocol")
 
   action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
     peek(requestNetwork_in, RequestMsg) {
-      enqueue(memQueue_out, MemoryMsg, 1) {
-        out_msg.Addr := address;
-        out_msg.Type := MemoryRequestType:MEMORY_READ;
-        out_msg.Sender := machineID;
-        out_msg.OriginalRequestorMachId := in_msg.Requestor;
-        out_msg.MessageSize := in_msg.MessageSize;
-        DPRINTF(RubySlicc, "%s\n", out_msg);
-      }
+      queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
     }
   }
 
   action(qp_queueMemoryForPersistent, "qp", desc="Queue off-chip fetch request") {
-    enqueue(memQueue_out, MemoryMsg, 1) {
-      out_msg.Addr := address;
-      out_msg.Type := MemoryRequestType:MEMORY_READ;
-      out_msg.Sender := machineID;
-      out_msg.OriginalRequestorMachId := persistentTable.findSmallest(address);
-      out_msg.MessageSize := MessageSizeType:Request_Control;
-      DPRINTF(RubySlicc, "%s\n", out_msg);
-    }
+    queueMemoryRead(persistentTable.findSmallest(address), address,
+                    to_memory_controller_latency);
   }
 
   action(fd_memoryDma, "fd", desc="Queue off-chip fetch request") {
     peek(dmaRequestQueue_in, DMARequestMsg) {
-      enqueue(memQueue_out, MemoryMsg, 1) {
-        out_msg.Addr := address;
-        out_msg.Type := MemoryRequestType:MEMORY_READ;
-        out_msg.Sender := machineID;
-        out_msg.OriginalRequestorMachId := in_msg.Requestor;
-        out_msg.MessageSize := in_msg.MessageSize;
-        DPRINTF(RubySlicc, "%s\n", out_msg);
-      }
+      queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
     }
   }
 
   action(lq_queueMemoryWbRequest, "lq", desc="Write data to memory") {
     peek(responseNetwork_in, ResponseMsg) {
-      enqueue(memQueue_out, MemoryMsg, 1) {
-        out_msg.Addr := address;
-        out_msg.Type := MemoryRequestType:MEMORY_WB;
-        out_msg.MessageSize := in_msg.MessageSize;
-        out_msg.DataBlk := in_msg.DataBlk;
-        DPRINTF(RubySlicc, "%s\n", out_msg);
-      }
+      queueMemoryWrite(in_msg.Sender, address, to_memory_controller_latency,
+                       in_msg.DataBlk);
     }
   }
 
   action(ld_queueMemoryDmaWriteFromTbe, "ld", desc="Write DMA data to memory") {
-    enqueue(memQueue_out, MemoryMsg, 1) {
-      out_msg.Addr := address;
-      out_msg.Type := MemoryRequestType:MEMORY_WB;
-      // first, initialize the data blk to the current version of system memory
-      out_msg.DataBlk := tbe.DataBlk;
-      // then add the dma write data
-      out_msg.DataBlk.copyPartial(
-        tbe.DmaDataBlk, addressOffset(tbe.PhysicalAddress), tbe.Len);
-      DPRINTF(RubySlicc, "%s\n", out_msg);
-    }
+    queueMemoryWritePartial(tbe.DmaRequestor, address,
+                            to_memory_controller_latency, tbe.DataBlk,
+                            tbe.Len);
   }
 
-  action(lr_queueMemoryDmaReadWriteback, "lr", desc="Write DMA data from read to memory") {
-    enqueue(memQueue_out, MemoryMsg, 1) {
-      out_msg.Addr := address;
-      out_msg.Type := MemoryRequestType:MEMORY_WB;
-      // first, initialize the data blk to the current version of system memory
-      out_msg.DataBlk := tbe.DataBlk;
-      DPRINTF(RubySlicc, "%s\n", out_msg);
+  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);
     }
   }
 
@@ -727,7 +690,7 @@ machine(Directory, "Token protocol")
     peek(dmaRequestQueue_in, DMARequestMsg) {
       TBEs.allocate(address);
       set_tbe(TBEs[address]);
-      tbe.DmaDataBlk := in_msg.DataBlk;
+      tbe.DataBlk := in_msg.DataBlk;
       tbe.PhysicalAddress := in_msg.PhysicalAddress;
       tbe.Len := in_msg.Len;
       tbe.DmaRequestor := in_msg.Requestor;
@@ -769,7 +732,10 @@ machine(Directory, "Token protocol")
 
   action(rd_recordDataInTbe, "rd", desc="Record data in TBE") {
     peek(responseNetwork_in, ResponseMsg) {
+      DataBlock DataBlk := tbe.DataBlk;
       tbe.DataBlk := in_msg.DataBlk;
+      tbe.DataBlk.copyPartial(DataBlk, addressOffset(tbe.PhysicalAddress),
+                              tbe.Len);
     }
   }
 
index 43d48c6d2065379843f01047ad2c05bd035d4ffb..e04573128520e70f5a93b17a221852521db3027f 100644 (file)
@@ -36,8 +36,8 @@
 machine(Directory, "AMD Hammer-like protocol") 
     : DirectoryMemory * directory;
       CacheMemory * probeFilter;
-      MemoryControl * memBuffer;
-      Cycles memory_controller_latency := 2;
+      Cycles from_memory_controller_latency := 2;
+      Cycles to_memory_controller_latency := 1;
       bool probe_filter_enabled := "False";
       bool full_bit_dir_enabled := "False";
 
@@ -271,17 +271,21 @@ machine(Directory, "AMD Hammer-like protocol")
     if(is_valid(tbe)) {
       testAndRead(addr, tbe.DataBlk, pkt);
     } else {
-      memBuffer.functionalRead(pkt);
+      functionalMemoryRead(pkt);
     }
   }
 
   int functionalWrite(Address addr, Packet *pkt) {
+    int num_functional_writes := 0;
+
     TBE tbe := TBEs[addr];
     if(is_valid(tbe)) {
-      testAndWrite(addr, tbe.DataBlk, pkt);
+      num_functional_writes := num_functional_writes +
+        testAndWrite(addr, tbe.DataBlk, pkt);
     }
 
-    return memBuffer.functionalWrite(pkt);
+    num_functional_writes := num_functional_writes + functionalMemoryWrite(pkt);
+    return num_functional_writes;
   }
 
   Event cache_request_to_event(CoherenceRequestType type) {
@@ -305,11 +309,6 @@ machine(Directory, "AMD Hammer-like protocol")
   out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir);
   out_port(triggerQueue_out, TriggerMsg, triggerQueue);
   
-  //
-  // Memory buffer for memory controller to DIMM communication
-  //
-  out_port(memQueue_out, MemoryMsg, memBuffer);
-
   // ** IN_PORTS **
   
   // Trigger Queue
@@ -389,7 +388,7 @@ machine(Directory, "AMD Hammer-like protocol")
   }
 
   // off-chip memory request/response is done
-  in_port(memQueue_in, MemoryMsg, memBuffer, rank=2) {
+  in_port(memQueue_in, MemoryMsg, responseFromMemory, rank=2) {
     if (memQueue_in.isReady()) {
       peek(memQueue_in, MemoryMsg) {
         PfEntry pf_entry := getProbeFilterEntry(in_msg.Addr);
@@ -503,7 +502,7 @@ machine(Directory, "AMD Hammer-like protocol")
 
   action(a_sendWriteBackAck, "a", desc="Send writeback ack to requestor") {
     peek(requestQueue_in, RequestMsg) {
-      enqueue(forwardNetwork_out, RequestMsg, memory_controller_latency) {
+      enqueue(forwardNetwork_out, RequestMsg, from_memory_controller_latency) {
         out_msg.Addr := address;
         out_msg.Type := CoherenceRequestType:WB_ACK;
         out_msg.Requestor := in_msg.Requestor;
@@ -516,7 +515,7 @@ machine(Directory, "AMD Hammer-like protocol")
   action(oc_sendBlockAck, "oc", desc="Send block ack to the owner") {
     peek(requestQueue_in, RequestMsg) {
         if (((probe_filter_enabled || full_bit_dir_enabled) && (in_msg.Requestor == cache_entry.Owner)) || machineCount(MachineType:L1Cache) == 1) {
-        enqueue(forwardNetwork_out, RequestMsg, memory_controller_latency) {
+        enqueue(forwardNetwork_out, RequestMsg, from_memory_controller_latency) {
           out_msg.Addr := address;
           out_msg.Type := CoherenceRequestType:BLOCK_ACK;
           out_msg.Requestor := in_msg.Requestor;
@@ -529,7 +528,7 @@ machine(Directory, "AMD Hammer-like protocol")
 
   action(b_sendWriteBackNack, "b", desc="Send writeback nack to requestor") {
     peek(requestQueue_in, RequestMsg) {
-      enqueue(forwardNetwork_out, RequestMsg, memory_controller_latency) {
+      enqueue(forwardNetwork_out, RequestMsg, from_memory_controller_latency) {
         out_msg.Addr := address;
         out_msg.Type := CoherenceRequestType:WB_NACK;
         out_msg.Requestor := in_msg.Requestor;
@@ -847,27 +846,13 @@ machine(Directory, "AMD Hammer-like protocol")
 
   action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
     peek(requestQueue_in, RequestMsg) {
-      enqueue(memQueue_out, MemoryMsg, 1) {
-        out_msg.Addr := address;
-        out_msg.Type := MemoryRequestType:MEMORY_READ;
-        out_msg.Sender := machineID;
-        out_msg.OriginalRequestorMachId := in_msg.Requestor;
-        out_msg.MessageSize := in_msg.MessageSize;
-        DPRINTF(RubySlicc, "%s\n", out_msg);
-      }
+      queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
     }
   }
 
   action(qd_queueMemoryRequestFromDmaRead, "qd", desc="Queue off-chip fetch request") {
     peek(dmaRequestQueue_in, DMARequestMsg) {
-      enqueue(memQueue_out, MemoryMsg, 1) {
-        out_msg.Addr := address;
-        out_msg.Type := MemoryRequestType:MEMORY_READ;
-        out_msg.Sender := machineID;
-        out_msg.OriginalRequestorMachId := in_msg.Requestor;
-        out_msg.MessageSize := in_msg.MessageSize;
-        DPRINTF(RubySlicc, "%s\n", out_msg);
-      }
+      queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
     }
   }
 
@@ -880,7 +865,7 @@ machine(Directory, "AMD Hammer-like protocol")
           fwd_set := cache_entry.Sharers;
           fwd_set.remove(machineIDToNodeID(in_msg.Requestor));
           if (fwd_set.count() > 0) {
-            enqueue(forwardNetwork_out, RequestMsg, memory_controller_latency) {
+            enqueue(forwardNetwork_out, RequestMsg, from_memory_controller_latency) {
               out_msg.Addr := address;
               out_msg.Type := in_msg.Type;
               out_msg.Requestor := in_msg.Requestor;
@@ -895,7 +880,7 @@ machine(Directory, "AMD Hammer-like protocol")
         }
       } else {
         peek(requestQueue_in, RequestMsg) {
-          enqueue(forwardNetwork_out, RequestMsg, memory_controller_latency) {
+          enqueue(forwardNetwork_out, RequestMsg, from_memory_controller_latency) {
             out_msg.Addr := address;
             out_msg.Type := in_msg.Type;
             out_msg.Requestor := in_msg.Requestor;
@@ -915,7 +900,7 @@ machine(Directory, "AMD Hammer-like protocol")
       if (full_bit_dir_enabled) {
         assert(cache_entry.Sharers.count() > 0);
         peek(requestQueue_in, RequestMsg) {
-          enqueue(forwardNetwork_out, RequestMsg, memory_controller_latency) {
+          enqueue(forwardNetwork_out, RequestMsg, from_memory_controller_latency) {
             out_msg.Addr := address;
             out_msg.Type := CoherenceRequestType:INV;
             out_msg.Requestor := machineID;
@@ -924,7 +909,7 @@ machine(Directory, "AMD Hammer-like protocol")
           }
         }
       } else {
-        enqueue(forwardNetwork_out, RequestMsg, memory_controller_latency) {
+        enqueue(forwardNetwork_out, RequestMsg, from_memory_controller_latency) {
           out_msg.Addr := address;
           out_msg.Type := CoherenceRequestType:INV;
           out_msg.Requestor := machineID;
@@ -937,7 +922,7 @@ machine(Directory, "AMD Hammer-like protocol")
 
   action(io_invalidateOwnerRequest, "io", desc="invalidate all copies") {
     if (machineCount(MachineType:L1Cache) > 1) {
-      enqueue(forwardNetwork_out, RequestMsg, memory_controller_latency) {
+      enqueue(forwardNetwork_out, RequestMsg, from_memory_controller_latency) {
         assert(is_valid(cache_entry)); 
         out_msg.Addr := address;
         out_msg.Type := CoherenceRequestType:INV;
@@ -956,7 +941,7 @@ machine(Directory, "AMD Hammer-like protocol")
           fwd_set := cache_entry.Sharers;
           fwd_set.remove(machineIDToNodeID(in_msg.Requestor));
           if (fwd_set.count() > 0) {
-            enqueue(forwardNetwork_out, RequestMsg, memory_controller_latency) {
+            enqueue(forwardNetwork_out, RequestMsg, from_memory_controller_latency) {
                   out_msg.Addr := address;
                   out_msg.Type := in_msg.Type;
                   out_msg.Requestor := in_msg.Requestor;
@@ -969,7 +954,7 @@ machine(Directory, "AMD Hammer-like protocol")
               }
           }
         } else {
-            enqueue(forwardNetwork_out, RequestMsg, memory_controller_latency) {
+            enqueue(forwardNetwork_out, RequestMsg, from_memory_controller_latency) {
                 out_msg.Addr := address;
                 out_msg.Type := in_msg.Type;
                 out_msg.Requestor := in_msg.Requestor;
@@ -1005,7 +990,7 @@ machine(Directory, "AMD Hammer-like protocol")
     // decouple the two.
     //
     peek(unblockNetwork_in, ResponseMsg) {
-      enqueue(forwardNetwork_out, RequestMsg, memory_controller_latency) {
+      enqueue(forwardNetwork_out, RequestMsg, from_memory_controller_latency) {
         assert(is_valid(tbe));
         out_msg.Addr := address;
         out_msg.Type := CoherenceRequestType:MERGED_GETS;
@@ -1026,7 +1011,7 @@ machine(Directory, "AMD Hammer-like protocol")
     assert(machineCount(MachineType:L1Cache) > 1);
     if (probe_filter_enabled || full_bit_dir_enabled) {
       peek(requestQueue_in, RequestMsg) {
-        enqueue(forwardNetwork_out, RequestMsg, memory_controller_latency) {
+        enqueue(forwardNetwork_out, RequestMsg, from_memory_controller_latency) {
           assert(is_valid(cache_entry)); 
           out_msg.Addr := address;
           out_msg.Type := in_msg.Type;
@@ -1040,7 +1025,7 @@ machine(Directory, "AMD Hammer-like protocol")
       }      
     } else {
       peek(requestQueue_in, RequestMsg) {
-        enqueue(forwardNetwork_out, RequestMsg, memory_controller_latency) {
+        enqueue(forwardNetwork_out, RequestMsg, from_memory_controller_latency) {
           out_msg.Addr := address;
           out_msg.Type := in_msg.Type;
           out_msg.Requestor := in_msg.Requestor;
@@ -1060,7 +1045,7 @@ machine(Directory, "AMD Hammer-like protocol")
      if (probe_filter_enabled || full_bit_dir_enabled) {
        peek(requestQueue_in, RequestMsg) {
         if (in_msg.Requestor != cache_entry.Owner) {
-          enqueue(forwardNetwork_out, RequestMsg, memory_controller_latency) {
+          enqueue(forwardNetwork_out, RequestMsg, from_memory_controller_latency) {
             assert(is_valid(cache_entry));
             out_msg.Addr := address;
             out_msg.Type := in_msg.Type;
@@ -1075,7 +1060,7 @@ machine(Directory, "AMD Hammer-like protocol")
        }
      } else {
       peek(requestQueue_in, RequestMsg) {
-        enqueue(forwardNetwork_out, RequestMsg, memory_controller_latency) {
+        enqueue(forwardNetwork_out, RequestMsg, from_memory_controller_latency) {
           out_msg.Addr := address;
           out_msg.Type := in_msg.Type;
           out_msg.Requestor := in_msg.Requestor;
@@ -1094,7 +1079,7 @@ machine(Directory, "AMD Hammer-like protocol")
     assert(is_valid(tbe));
     if (tbe.NumPendingMsgs > 0) {
       peek(dmaRequestQueue_in, DMARequestMsg) {
-        enqueue(forwardNetwork_out, RequestMsg, memory_controller_latency) {
+        enqueue(forwardNetwork_out, RequestMsg, from_memory_controller_latency) {
           out_msg.Addr := address;
           out_msg.Type := CoherenceRequestType:GETX;
           //
@@ -1113,7 +1098,7 @@ machine(Directory, "AMD Hammer-like protocol")
     assert(is_valid(tbe));
     if (tbe.NumPendingMsgs > 0) {
       peek(dmaRequestQueue_in, DMARequestMsg) {
-        enqueue(forwardNetwork_out, RequestMsg, memory_controller_latency) {
+        enqueue(forwardNetwork_out, RequestMsg, from_memory_controller_latency) {
           out_msg.Addr := address;
           out_msg.Type := CoherenceRequestType:GETS;
           //
@@ -1221,38 +1206,21 @@ machine(Directory, "AMD Hammer-like protocol")
 
   action(l_queueMemoryWBRequest, "lq", desc="Write PUTX data to memory") {
     peek(unblockNetwork_in, ResponseMsg) {
-      enqueue(memQueue_out, MemoryMsg, 1) {
-        assert(in_msg.Dirty);
-        assert(in_msg.MessageSize == MessageSizeType:Writeback_Data);
-        out_msg.Addr := address;
-        out_msg.Type := MemoryRequestType:MEMORY_WB;
-        out_msg.DataBlk := in_msg.DataBlk;
-        DPRINTF(RubySlicc, "%s\n", out_msg);
-      }
+      queueMemoryWrite(in_msg.Sender, address, to_memory_controller_latency,
+                       in_msg.DataBlk);
     }
   }
 
   action(ld_queueMemoryDmaWrite, "ld", desc="Write DMA data to memory") {
-    enqueue(memQueue_out, MemoryMsg, 1) {
-      assert(is_valid(tbe));
-      out_msg.Addr := address;
-      out_msg.Type := MemoryRequestType:MEMORY_WB;
-      // first, initialize the data blk to the current version of system memory
-      out_msg.DataBlk := tbe.DataBlk;
-      // then add the dma write data
-      out_msg.DataBlk.copyPartial(tbe.DmaDataBlk, addressOffset(tbe.PhysicalAddress), tbe.Len);
-      DPRINTF(RubySlicc, "%s\n", out_msg);
-    }
+    assert(is_valid(tbe));
+    queueMemoryWritePartial(tbe.DmaRequestor, tbe.PhysicalAddress,
+                            to_memory_controller_latency, tbe.DmaDataBlk,
+                            tbe.Len);
   }
 
   action(ly_queueMemoryWriteFromTBE, "ly", desc="Write data to memory from TBE") {
-    enqueue(memQueue_out, MemoryMsg, 1) {
-      assert(is_valid(tbe));
-      out_msg.Addr := address;
-      out_msg.Type := MemoryRequestType:MEMORY_WB;
-      out_msg.DataBlk := tbe.DataBlk;
-      DPRINTF(RubySlicc, "%s\n", out_msg);
-    }
+    queueMemoryWrite(machineID, address, to_memory_controller_latency,
+                     tbe.DataBlk);
   }
 
   action(ll_checkIncomingWriteback, "\l", desc="Check PUTX/PUTO response message") {
index 1480790bf6b0af9a7748f0ac38ab7281158ad958..514a307dfd4a8cf9540a45dad904dd68d809f8af 100644 (file)
 NodeID version;
 MachineID machineID;
 NodeID clusterID;
+MessageBuffer responseFromMemory, ordered="false";
+
+// Functions implemented in the AbstractController class for
+// making timing access to the memory maintained by the
+// memory controllers.
+void queueMemoryRead(MachineID id, Address addr, Cycles latency);
+void queueMemoryWrite(MachineID id, Address addr, Cycles latency,
+                      DataBlock block);
+void queueMemoryWritePartial(MachineID id, Address 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.
+void functionalMemoryRead(Packet *pkt);
+bool functionalMemoryWrite(Packet *pkt);
index 2d0658e68c6e1cd262bcefbb96b9126353bc68eb..fb506781cc6142c93e55d97bb1a193b2a2d09c1d 100644 (file)
@@ -161,12 +161,6 @@ structure (WireBuffer, inport="yes", outport="yes", external = "yes") {
 
 }
 
-structure (MemoryControl, inport="yes", outport="yes", external = "yes") {
-  void recordRequestType(CacheRequestType);
-  void functionalRead(Packet *pkt);
-  int functionalWrite(Packet *pkt);
-}
-
 structure (DMASequencer, external = "yes") {
   void ackCallback();
   void dataCallback(DataBlock);
index 4200ddaebd41385fd247865d46e947aaffae4f9b..8133820b9ddb2a040699951c33119ee7c1a007a5 100644 (file)
@@ -126,7 +126,6 @@ MakeInclude('structures/Prefetcher.hh')
 MakeInclude('structures/CacheMemory.hh')
 MakeInclude('system/DMASequencer.hh')
 MakeInclude('structures/DirectoryMemory.hh')
-MakeInclude('structures/MemoryControl.hh')
 MakeInclude('structures/WireBuffer.hh')
 MakeInclude('structures/PerfectCacheMemory.hh')
 MakeInclude('structures/PersistentTable.hh')
index 1bc55c2c97f47d4936a0ab808b5c4dd5a7720c71..57a8d551990cd9cbcec083605663b74f78388203 100644 (file)
@@ -144,16 +144,16 @@ random_time()
 void
 MessageBuffer::enqueue(MsgPtr message, Cycles delta)
 {
-    m_msg_counter++;
+    assert(m_ordering_set);
 
     // record current time incase we have a pop that also adjusts my size
     if (m_time_last_time_enqueue < m_sender->curCycle()) {
         m_msgs_this_cycle = 0;  // first msg this cycle
         m_time_last_time_enqueue = m_sender->curCycle();
     }
-    m_msgs_this_cycle++;
 
-    assert(m_ordering_set);
+    m_msg_counter++;
+    m_msgs_this_cycle++;
 
     // Calculate the arrival time of the message, that is, the first
     // cycle the message can be dequeued.
index 366ea04ce56bbbc1a43dcef395ae26d30b17fdca..6bcbfbcbf1c5ee86dbd0e6da00b973a24a78fd58 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011 Mark D. Hill and David A. Wood
+ * Copyright (c) 2011-2014 Mark D. Hill and David A. Wood
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "mem/protocol/MemoryMsg.hh"
 #include "mem/ruby/slicc_interface/AbstractController.hh"
 #include "mem/ruby/system/Sequencer.hh"
 #include "mem/ruby/system/System.hh"
+#include "sim/system.hh"
 
 AbstractController::AbstractController(const Params *p)
-    : ClockedObject(p), Consumer(this)
+    : MemObject(p), Consumer(this), m_version(p->version),
+      m_clusterID(p->cluster_id),
+      m_masterId(p->system->getMasterId(name())), m_is_blocking(false),
+      m_number_of_TBEs(p->number_of_TBEs),
+      m_transitions_per_cycle(p->transitions_per_cycle),
+      m_buffer_size(p->buffer_size), m_recycle_latency(p->recycle_latency),
+      memoryPort(csprintf("%s.memory", name()), this, ""),
+      m_responseFromMemory_ptr(new MessageBuffer())
 {
-    m_version = p->version;
-    m_clusterID = p->cluster_id;
-
-    m_transitions_per_cycle = p->transitions_per_cycle;
-    m_buffer_size = p->buffer_size;
-    m_recycle_latency = p->recycle_latency;
-    m_number_of_TBEs = p->number_of_TBEs;
-    m_is_blocking = false;
+    // Set the sender pointer of the response message buffer from the
+    // memory controller.
+    // This pointer is used for querying for the current time.
+    m_responseFromMemory_ptr->setSender(this);
+    m_responseFromMemory_ptr->setReceiver(this);
+    m_responseFromMemory_ptr->setOrdering(false);
 
     if (m_version == 0) {
         // Combine the statistics from all controllers
@@ -187,3 +194,140 @@ AbstractController::unblock(Address addr)
        m_is_blocking = false;
     }
 }
+
+BaseMasterPort &
+AbstractController::getMasterPort(const std::string &if_name,
+                                  PortID idx)
+{
+    return memoryPort;
+}
+
+void
+AbstractController::queueMemoryRead(const MachineID &id, Address addr,
+                                    Cycles latency)
+{
+    RequestPtr req = new Request(addr.getAddress(),
+                                 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);
+
+    memoryPort.schedTimingReq(pkt, clockEdge(latency));
+}
+
+void
+AbstractController::queueMemoryWrite(const MachineID &id, Address addr,
+                                     Cycles latency, const DataBlock &block)
+{
+    RequestPtr req = new Request(addr.getAddress(),
+                                 RubySystem::getBlockSizeBytes(), 0,
+                                 m_masterId);
+
+    PacketPtr pkt = Packet::createWrite(req);
+    uint8_t *newData = new uint8_t[RubySystem::getBlockSizeBytes()];
+    pkt->dataDynamic(newData);
+    memcpy(newData, block.getData(0, RubySystem::getBlockSizeBytes()),
+           RubySystem::getBlockSizeBytes());
+
+    SenderState *s = new SenderState(id);
+    pkt->pushSenderState(s);
+
+    // Create a block and copy data from the block.
+    memoryPort.schedTimingReq(pkt, clockEdge(latency));
+}
+
+void
+AbstractController::queueMemoryWritePartial(const MachineID &id, Address addr,
+                                            Cycles latency,
+                                            const DataBlock &block, int size)
+{
+    RequestPtr req = new Request(addr.getAddress(),
+                                 RubySystem::getBlockSizeBytes(), 0,
+                                 m_masterId);
+
+    PacketPtr pkt = Packet::createWrite(req);
+    uint8_t *newData = new uint8_t[size];
+    pkt->dataDynamic(newData);
+    memcpy(newData, block.getData(addr.getOffset(), size), 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)
+{
+    memoryPort.sendFunctional(pkt);
+}
+
+int
+AbstractController::functionalMemoryWrite(PacketPtr pkt)
+{
+    int num_functional_writes = 0;
+
+    // Check the message buffer that runs from the memory to the controller.
+    num_functional_writes += m_responseFromMemory_ptr->functionalWrite(pkt);
+
+    // Check the buffer from the controller to the memory.
+    if (memoryPort.checkFunctional(pkt)) {
+        num_functional_writes++;
+    }
+
+    // Update memory itself.
+    memoryPort.sendFunctional(pkt);
+    return num_functional_writes + 1;
+}
+
+void
+AbstractController::recvTimingResp(PacketPtr pkt)
+{
+    assert(pkt->isResponse());
+
+    std::shared_ptr<MemoryMsg> msg = std::make_shared<MemoryMsg>(clockEdge());
+    (*msg).m_Addr.setAddress(pkt->getAddr());
+    (*msg).m_Sender = m_machineID;
+
+    SenderState *s = dynamic_cast<SenderState *>(pkt->senderState);
+    (*msg).m_OriginalRequestorMachId = s->id;
+    delete s;
+
+    if (pkt->isRead()) {
+        (*msg).m_Type = MemoryRequestType_MEMORY_READ;
+        (*msg).m_MessageSize = MessageSizeType_Response_Data;
+
+        // Copy data from the packet
+        (*msg).m_DataBlk.setData(pkt->getPtr<uint8_t>(), 0,
+                                 RubySystem::getBlockSizeBytes());
+    } else if (pkt->isWrite()) {
+        (*msg).m_Type = MemoryRequestType_MEMORY_WB;
+        (*msg).m_MessageSize = MessageSizeType_Writeback_Control;
+    } else {
+        panic("Incorrect packet type received from memory controller!");
+    }
+
+    m_responseFromMemory_ptr->enqueue(msg);
+    delete pkt;
+}
+
+bool
+AbstractController::MemoryPort::recvTimingResp(PacketPtr pkt)
+{
+    controller->recvTimingResp(pkt);
+    return true;
+}
+
+AbstractController::MemoryPort::MemoryPort(const std::string &_name,
+                                           AbstractController *_controller,
+                                           const std::string &_label)
+    : QueuedMasterPort(_name, _controller, _queue),
+      _queue(*_controller, *this, _label), controller(_controller)
+{
+}
index 98fce574f9ac9c616bda9eee3566376da7957873..45d355b3e3fa6ac906e4e38488b60896d63e2291 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009-2014 Mark D. Hill and David A. Wood
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #include "mem/ruby/network/Network.hh"
 #include "mem/ruby/system/CacheRecorder.hh"
 #include "mem/packet.hh"
+#include "mem/qport.hh"
 #include "params/RubyController.hh"
-#include "sim/clocked_object.hh"
+#include "mem/mem_object.hh"
 
 class Network;
 
-class AbstractController : public ClockedObject, public Consumer
+class AbstractController : public MemObject, public Consumer
 {
   public:
     typedef RubyControllerParams Params;
@@ -79,10 +80,12 @@ class AbstractController : public ClockedObject, public Consumer
     //! These functions are used by ruby system to read/write the data blocks
     //! that exist with in the controller.
     virtual void functionalRead(const Address &addr, PacketPtr) = 0;
+    void functionalMemoryRead(PacketPtr);
     //! The return value indicates the number of messages written with the
     //! data from the packet.
-    virtual uint32_t functionalWriteBuffers(PacketPtr&) = 0;
+    virtual int functionalWriteBuffers(PacketPtr&) = 0;
     virtual int functionalWrite(const Address &addr, PacketPtr) = 0;
+    int functionalMemoryWrite(PacketPtr);
 
     //! Function for enqueuing a prefetch request
     virtual void enqueuePrefetch(const Address&, const RubyRequestType&)
@@ -97,6 +100,17 @@ class AbstractController : public ClockedObject, public Consumer
     //! Set the message buffer with given name.
     virtual void setNetQueue(const std::string& name, MessageBuffer *b) = 0;
 
+    /** A function used to return the port associated with this bus object. */
+    BaseMasterPort& getMasterPort(const std::string& if_name,
+                                  PortID idx = InvalidPortID);
+
+    void queueMemoryRead(const MachineID &id, Address addr, Cycles latency);
+    void queueMemoryWrite(const MachineID &id, Address addr, Cycles latency,
+                          const DataBlock &block);
+    void queueMemoryWritePartial(const MachineID &id, Address addr, Cycles latency,
+                                 const DataBlock &block, int size);
+    void recvTimingResp(PacketPtr pkt);
+
   public:
     MachineID getMachineID() const { return m_machineID; }
 
@@ -120,6 +134,9 @@ class AbstractController : public ClockedObject, public Consumer
     MachineID m_machineID;
     NodeID m_clusterID;
 
+    // MasterID used by some components of gem5.
+    MasterID m_masterId;
+
     Network* m_net_ptr;
     bool m_is_blocking;
     std::map<Address, MessageBuffer*> m_block_map;
@@ -156,6 +173,46 @@ class AbstractController : public ClockedObject, public Consumer
         StatsCallback(AbstractController *_ctr) : ctr(_ctr) {}
         void process() {ctr->collateStats();}
     };
+
+    /**
+     * Port that forwards requests and receives responses from the
+     * memory controller.  It has a queue of packets not yet sent.
+     */
+    class MemoryPort : public QueuedMasterPort
+    {
+      private:
+        // Packet queue used to store outgoing requests and responses.
+        MasterPacketQueue _queue;
+
+        // Controller that operates this port.
+        AbstractController *controller;
+
+      public:
+        MemoryPort(const std::string &_name, AbstractController *_controller,
+                   const std::string &_label);
+
+        // Function for receiving a timing response from the peer port.
+        // Currently the pkt is handed to the coherence controller
+        // associated with this port.
+        bool recvTimingResp(PacketPtr pkt);
+    };
+
+    /* Master port to the memory controller. */
+    MemoryPort memoryPort;
+
+    // Message Buffer for storing the response received from the
+    // memory controller.
+    MessageBuffer *m_responseFromMemory_ptr;
+
+    // State that is stored in packets sent to the memory controller.
+    struct SenderState : public Packet::SenderState
+    {
+        // Id of the machine from which the request originated.
+        MachineID id;
+
+        SenderState(MachineID _id) : id(_id)
+        {}
+    };
 };
 
 #endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__
index f82e0a70d625cd7147d57b15884a8f0c9ec71c80..ba7d17c7c5c8a8060b5268a956889f97bae3e9ba 100644 (file)
 #          Brad Beckmann
 
 from m5.params import *
-from ClockedObject import ClockedObject
+from m5.proxy import *
+from MemObject import MemObject
 
-class RubyController(ClockedObject):
+class RubyController(MemObject):
     type = 'RubyController'
     cxx_class = 'AbstractController'
     cxx_header = "mem/ruby/slicc_interface/AbstractController.hh"
@@ -46,4 +47,5 @@ class RubyController(ClockedObject):
     number_of_TBEs = Param.Int(256, "")
     ruby_system = Param.RubySystem("")
 
-    peer = Param.RubyController(NULL, "")
+    memory = MasterPort("Port for attaching a memory controller")
+    system = Param.System(Parent.any, "system object parameter")
index 14a35923390e0ef78027d12a21edb7bf65e42cab..c6e165e3a89226c466afff6a47b689afe8a6452a 100644 (file)
@@ -29,7 +29,6 @@
 
 from m5.params import *
 from m5.SimObject import SimObject
-from Controller import RubyController
 
 class RubyCache(SimObject):
     type = 'RubyCache'
index c64439ce51b20e5dbf55ee918b66d354d6b6918d..bb9765bdbbd1041caafaf05b355554edb63c1b2b 100644 (file)
@@ -37,8 +37,6 @@ class RubyDirectoryMemory(SimObject):
     cxx_header = "mem/ruby/structures/DirectoryMemory.hh"
     version = Param.Int(0, "")
     size = Param.MemorySize("1GB", "capacity in bytes")
-    use_map = Param.Bool(False, "enable sparse memory")
-    map_levels = Param.Int(4, "sparse memory map levels")
     # the default value of the numa high bit is specified in the command line
     # option and must be passed into the directory memory sim object
     numa_high_bit = Param.Int("numa high bit")
diff --git a/src/mem/ruby/structures/MemoryControl.cc b/src/mem/ruby/structures/MemoryControl.cc
deleted file mode 100644 (file)
index 6c933b4..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * Copyright (c) 2012 Advanced Micro Devices, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "debug/RubyStats.hh"
-#include "mem/ruby/common/Global.hh"
-#include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh"
-#include "mem/ruby/structures/MemoryControl.hh"
-#include "mem/ruby/system/System.hh"
-
-using namespace std;
-MemoryControl::MemoryControl(const Params *p)
-    : ClockedObject(p), Consumer(this), m_event(this)
-{
-    g_system_ptr->registerMemController(this);
-}
-
-MemoryControl::~MemoryControl() {};
-
-void
-MemoryControl::recordRequestType(MemoryControlRequestType request) {
-    DPRINTF(RubyStats, "Recorded request: %s\n",
-            MemoryControlRequestType_to_string(request));
-}
diff --git a/src/mem/ruby/structures/MemoryControl.hh b/src/mem/ruby/structures/MemoryControl.hh
deleted file mode 100644 (file)
index b1cbe98..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * Copyright (c) 2012 Advanced Micro Devices, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __MEM_RUBY_STRUCTURES_ABSTRACT_MEMORY_CONTROL_HH__
-#define __MEM_RUBY_STRUCTURES_ABSTRACT_MEMORY_CONTROL_HH__
-
-#include <iostream>
-#include <list>
-#include <string>
-
-#include "mem/protocol/MemoryControlRequestType.hh"
-#include "mem/ruby/common/Consumer.hh"
-#include "mem/ruby/slicc_interface/Message.hh"
-#include "mem/ruby/structures/MemoryNode.hh"
-#include "params/MemoryControl.hh"
-#include "sim/clocked_object.hh"
-
-//////////////////////////////////////////////////////////////////////////////
-
-class MemoryControl : public ClockedObject, public Consumer
-{
-  public:
-    typedef MemoryControlParams Params;
-    const Params *params() const
-    { return dynamic_cast<const Params *>(_params); }
-
-    MemoryControl(const Params *p);
-    virtual void init() = 0;
-    virtual void reset() = 0;
-
-    ~MemoryControl();
-
-    virtual void wakeup() = 0;
-
-    virtual void setConsumer(Consumer* consumer_ptr) = 0;
-    virtual Consumer* getConsumer() = 0;
-    virtual void setClockObj(ClockedObject* consumer_ptr) {}
-
-    virtual void setDescription(const std::string& name) = 0;
-    virtual std::string getDescription() = 0;
-
-    // Called from the directory:
-    virtual void enqueue(const MsgPtr& message, Cycles latency) = 0;
-    virtual void enqueueMemRef(MemoryNode *memRef) = 0;
-    virtual void dequeue() = 0;
-    virtual const Message* peek() = 0;
-    virtual MemoryNode *peekNode() = 0;
-    virtual bool isReady() = 0;
-    virtual bool areNSlotsAvailable(int n) = 0;  // infinite queue length
-
-    virtual void print(std::ostream& out) const = 0;
-    virtual void regStats() {};
-
-    virtual const int getChannel(const physical_address_t addr) const = 0;
-    virtual const int getBank(const physical_address_t addr) const = 0;
-    virtual const int getRank(const physical_address_t addr) const = 0;
-    virtual const int getRow(const physical_address_t addr) const = 0;
-
-    //added by SS
-    virtual int getBanksPerRank() = 0;
-    virtual int getRanksPerDimm() = 0;
-    virtual int getDimmsPerChannel() = 0;
-
-    virtual void recordRequestType(MemoryControlRequestType requestType);
-
-    virtual bool functionalRead(Packet *pkt)
-    { fatal("Functional read access not implemented!");}
-    virtual uint32_t functionalWrite(Packet *pkt)
-    { fatal("Functional read access not implemented!");}
-
-protected:
-    class MemCntrlEvent : public Event
-    {
-      public:
-        MemCntrlEvent(MemoryControl* _mem_cntrl)
-        {
-            mem_cntrl = _mem_cntrl;
-        }
-      private:
-        void process() { mem_cntrl->wakeup(); }
-
-        MemoryControl* mem_cntrl;
-    };
-
-    MemCntrlEvent m_event;
-};
-
-#endif //   __MEM_RUBY_STRUCTURES_ABSTRACT_MEMORY_CONTROL_HH__
diff --git a/src/mem/ruby/structures/MemoryControl.py b/src/mem/ruby/structures/MemoryControl.py
deleted file mode 100644 (file)
index 8a6879c..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (c) 2009 Advanced Micro Devices, Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met: redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer;
-# redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution;
-# neither the name of the copyright holders nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# Authors: Steve Reinhardt
-#          Brad Beckmann
-
-from m5.params import *
-from ClockedObject import ClockedObject
-
-class MemoryControl(ClockedObject):
-    abstract = True
-    type = 'MemoryControl'
-    cxx_class = 'MemoryControl'
-    cxx_header = "mem/ruby/structures/MemoryControl.hh"
-    version = Param.Int("");
-    ruby_system = Param.RubySystem("")
index 2a5cbb18991a687a355679a3c73648f6991f3512..1e68cc4595266a4b0558c4e9049bdc1b48924516 100644 (file)
@@ -36,6 +36,6 @@ MemoryNode::print(ostream& out) const
     out << "[";
     out << m_time << ", ";
     out << m_msg_counter << ", ";
-    out << m_msgptr << "; ";
+    out << pkt << "; ";
     out << "]";
 }
index 3f40e3648dbb52e22840989d3ffb231304dea3e6..b48f64704463af518a8b731a9ea7a94f12c6d741 100644 (file)
@@ -47,25 +47,23 @@ class MemoryNode
 {
   public:
     // old constructor
-    MemoryNode(const Cycles& time, int counter, const MsgPtr& msgptr,
+    MemoryNode(const Cycles& time, int counter, const PacketPtr p,
                const physical_address_t addr, const bool is_mem_read)
-        : m_time(time)
+        : m_time(time), pkt(p)
     {
         m_msg_counter = counter;
-        m_msgptr = msgptr;
         m_addr = addr;
         m_is_mem_read = is_mem_read;
         m_is_dirty_wb = !is_mem_read;
     }
 
     // new constructor
-    MemoryNode(const Cycles& time, const MsgPtr& msgptr,
+    MemoryNode(const Cycles& time, const PacketPtr p,
                const physical_address_t addr, const bool is_mem_read,
                const bool is_dirty_wb)
-        : m_time(time)
+        : m_time(time), pkt(p)
     {
         m_msg_counter = 0;
-        m_msgptr = msgptr;
         m_addr = addr;
         m_is_mem_read = is_mem_read;
         m_is_dirty_wb = is_dirty_wb;
@@ -75,7 +73,7 @@ class MemoryNode
 
     Cycles m_time;
     int m_msg_counter;
-    MsgPtr m_msgptr;
+    PacketPtr pkt;
     physical_address_t m_addr;
     bool m_is_mem_read;
     bool m_is_dirty_wb;
diff --git a/src/mem/ruby/structures/MemoryVector.hh b/src/mem/ruby/structures/MemoryVector.hh
deleted file mode 100644 (file)
index 384c68a..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright (c) 2009 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __MEM_RUBY_STRUCTURES_MEMORYVECTOR_HH__
-#define __MEM_RUBY_STRUCTURES_MEMORYVECTOR_HH__
-
-#include "base/trace.hh"
-#include "debug/RubyCacheTrace.hh"
-#include "mem/ruby/common/Address.hh"
-
-class DirectoryMemory;
-
-/**
- *  MemoryVector holds memory data (DRAM only)
- */
-class MemoryVector
-{
-  public:
-    MemoryVector();
-    MemoryVector(uint64 size);
-    ~MemoryVector();
-    friend class DirectoryMemory;
-
-    void resize(uint64 size);  // destructive
-
-    void write(const Address & paddr, uint8_t *data, int len);
-    uint8_t *read(const Address & paddr, uint8_t *data, int len);
-    uint32_t collatePages(uint8_t *&raw_data);
-    void populatePages(uint8_t *raw_data);
-
-  private:
-    uint8_t *getBlockPtr(const PhysAddress & addr);
-
-    uint64 m_size;
-    uint8_t **m_pages;
-    uint32_t m_num_pages;
-    const uint32_t m_page_offset_mask;
-    static const uint32_t PAGE_SIZE = 4096;
-};
-
-inline
-MemoryVector::MemoryVector()
-    : m_page_offset_mask(4095)
-{
-    m_size = 0;
-    m_num_pages = 0;
-    m_pages = NULL;
-}
-
-inline
-MemoryVector::MemoryVector(uint64 size)
-    : m_page_offset_mask(4095)
-{
-    resize(size);
-}
-
-inline
-MemoryVector::~MemoryVector()
-{
-    for (int i = 0; i < m_num_pages; i++) {
-        if (m_pages[i] != 0) {
-            delete [] m_pages[i];
-        }
-    }
-    delete [] m_pages;
-}
-
-inline void
-MemoryVector::resize(uint64 size)
-{
-    if (m_pages != NULL){
-        for (int i = 0; i < m_num_pages; i++) {
-            if (m_pages[i] != 0) {
-                delete [] m_pages[i];
-            }
-        }
-        delete [] m_pages;
-    }
-    m_size = size;
-    assert(size%PAGE_SIZE == 0);
-    m_num_pages = size >> 12;
-    m_pages = new uint8_t*[m_num_pages];
-    memset(m_pages, 0, m_num_pages * sizeof(uint8_t*));
-}
-
-inline void
-MemoryVector::write(const Address & paddr, uint8_t *data, int len)
-{
-    assert(paddr.getAddress() + len <= m_size);
-    uint32_t page_num = paddr.getAddress() >> 12;
-    if (m_pages[page_num] == 0) {
-        bool all_zeros = true;
-        for (int i = 0; i < len;i++) {
-            if (data[i] != 0) {
-                all_zeros = false;
-                break;
-            }
-        }
-        if (all_zeros)
-            return;
-        m_pages[page_num] = new uint8_t[PAGE_SIZE];
-        memset(m_pages[page_num], 0, PAGE_SIZE);
-        uint32_t offset = paddr.getAddress() & m_page_offset_mask;
-        memcpy(&m_pages[page_num][offset], data, len);
-    } else {
-        memcpy(&m_pages[page_num][paddr.getAddress()&m_page_offset_mask],
-               data, len);
-    }
-}
-
-inline uint8_t*
-MemoryVector::read(const Address & paddr, uint8_t *data, int len)
-{
-    assert(paddr.getAddress() + len <= m_size);
-    uint32_t page_num = paddr.getAddress() >> 12;
-    if (m_pages[page_num] == 0) {
-        memset(data, 0, len);
-    } else {
-        memcpy(data, &m_pages[page_num][paddr.getAddress()&m_page_offset_mask],
-               len);
-    }
-    return data;
-}
-
-inline uint8_t*
-MemoryVector::getBlockPtr(const PhysAddress & paddr)
-{
-    uint32_t page_num = paddr.getAddress() >> 12;
-    if (m_pages[page_num] == 0) {
-        m_pages[page_num] = new uint8_t[PAGE_SIZE];
-        memset(m_pages[page_num], 0, PAGE_SIZE);
-    }
-    return &m_pages[page_num][paddr.getAddress()&m_page_offset_mask];
-}
-
-/*!
- * Function for collating all the pages of the physical memory together.
- * In case a pointer for a page is NULL, this page needs only a single byte
- * to represent that the pointer is NULL. Otherwise, it needs 1 + PAGE_SIZE
- * bytes. The first represents that the page pointer is not NULL, and rest of
- * the bytes represent the data on the page.
- */
-
-inline uint32_t
-MemoryVector::collatePages(uint8_t *&raw_data)
-{
-    uint32_t num_zero_pages = 0;
-    uint32_t data_size = 0;
-
-    for (uint32_t i = 0;i < m_num_pages; ++i)
-    {
-        if (m_pages[i] == 0) num_zero_pages++;
-    }
-
-    raw_data = new uint8_t[sizeof(uint32_t) /* number of pages*/ +
-                           m_num_pages /* whether the page is all zeros */ +
-                           PAGE_SIZE * (m_num_pages - num_zero_pages)];
-
-    /* Write the number of pages to be stored. */
-    memcpy(raw_data, &m_num_pages, sizeof(uint32_t));
-    data_size = sizeof(uint32_t);
-
-    DPRINTF(RubyCacheTrace, "collating %d pages\n", m_num_pages);
-
-    for (uint32_t i = 0;i < m_num_pages; ++i)
-    {
-        if (m_pages[i] == 0) {
-            raw_data[data_size] = 0;
-        } else {
-            raw_data[data_size] = 1;
-            memcpy(raw_data + data_size + 1, m_pages[i], PAGE_SIZE);
-            data_size += PAGE_SIZE;
-        }
-        data_size += 1;
-    }
-
-    return data_size;
-}
-
-/*!
- * Function for populating the pages of the memory using the available raw
- * data. Each page has a byte associate with it, which represents whether the
- * page was NULL or not, when all the pages were collated. The function assumes
- * that the number of pages in the memory are same as those that were recorded
- * in the checkpoint.
- */
-inline void
-MemoryVector::populatePages(uint8_t *raw_data)
-{
-    uint32_t data_size = 0;
-    uint32_t num_pages = 0;
-
-    /* Read the number of pages that were stored. */
-    memcpy(&num_pages, raw_data, sizeof(uint32_t));
-    data_size = sizeof(uint32_t);
-    assert(num_pages == m_num_pages);
-
-    DPRINTF(RubyCacheTrace, "Populating %d pages\n", num_pages);
-
-    for (uint32_t i = 0;i < m_num_pages; ++i)
-    {
-        assert(m_pages[i] == 0);
-        if (raw_data[data_size] != 0) {
-            m_pages[i] = new uint8_t[PAGE_SIZE];
-            memcpy(m_pages[i], raw_data + data_size + 1, PAGE_SIZE);
-            data_size += PAGE_SIZE;
-        }
-        data_size += 1;
-    }
-}
-
-#endif // __MEM_RUBY_STRUCTURES_MEMORYVECTOR_HH__
index 2e71c0c2ffc40739721d3e4d1777b56ad70fa5c0..a7a815adbb7b23ca4dfb678e21297dc7d46d9389 100644 (file)
@@ -145,7 +145,8 @@ operator<<(ostream& out, const RubyMemoryControl& obj)
 
 // CONSTRUCTOR
 RubyMemoryControl::RubyMemoryControl(const Params *p)
-    : MemoryControl(p)
+    : AbstractMemory(p), Consumer(this), port(name() + ".port", *this),
+      m_event(this)
 {
     m_banks_per_rank = p->banks_per_rank;
     m_ranks_per_dimm = p->ranks_per_dimm;
@@ -173,9 +174,7 @@ RubyMemoryControl::RubyMemoryControl(const Params *p)
 void
 RubyMemoryControl::init()
 {
-    m_ram = g_system_ptr->getMemoryVector();
     m_msg_counter = 0;
-
     assert(m_tFaw <= 62); // must fit in a uint64 shift register
 
     m_total_banks = m_banks_per_rank * m_ranks_per_dimm * m_dimms_per_channel;
@@ -221,6 +220,16 @@ RubyMemoryControl::init()
     }
 }
 
+BaseSlavePort&
+RubyMemoryControl::getSlavePort(const string &if_name, PortID idx)
+{
+    if (if_name != "port") {
+        return MemObject::getSlavePort(if_name, idx);
+    } else {
+        return port;
+    }
+}
+
 void
 RubyMemoryControl::reset()
 {
@@ -275,30 +284,18 @@ RubyMemoryControl::~RubyMemoryControl()
 }
 
 // enqueue new request from directory
-void
-RubyMemoryControl::enqueue(const MsgPtr& message, Cycles latency)
+bool
+RubyMemoryControl::recvTimingReq(PacketPtr pkt)
 {
-    Cycles arrival_time = curCycle() + latency;
-    const MemoryMsg* memMess = safe_cast<const MemoryMsg*>(message.get());
-    physical_address_t addr = memMess->getAddr().getAddress();
-    MemoryRequestType type = memMess->getType();
-    bool is_mem_read = (type == MemoryRequestType_MEMORY_READ);
-
-    if (is_mem_read) {
-        m_ram->read(memMess->getAddr(), const_cast<uint8_t *>(
-                    memMess->getDataBlk().getData(0,
-                        RubySystem::getBlockSizeBytes())),
-                    RubySystem::getBlockSizeBytes());
-    }  else {
-        m_ram->write(memMess->getAddr(), const_cast<uint8_t *>(
-                     memMess->getDataBlk().getData(0,
-                         RubySystem::getBlockSizeBytes())),
-                     RubySystem::getBlockSizeBytes());
-    }
-
-    MemoryNode *thisReq = new MemoryNode(arrival_time, message, addr,
+    Cycles arrival_time = curCycle();
+    physical_address_t addr = pkt->getAddr();
+    bool is_mem_read = pkt->isRead();
+
+    access(pkt);
+    MemoryNode *thisReq = new MemoryNode(arrival_time, pkt, addr,
                                          is_mem_read, !is_mem_read);
     enqueueMemRef(thisReq);
+    return true;
 }
 
 // Alternate entry point used when we already have a MemoryNode
@@ -325,51 +322,6 @@ RubyMemoryControl::enqueueMemRef(MemoryNode *memRef)
     }
 }
 
-// dequeue, peek, and isReady are used to transfer completed requests
-// back to the directory
-void
-RubyMemoryControl::dequeue()
-{
-    assert(isReady());
-    MemoryNode *req = m_response_queue.front();
-    m_response_queue.pop_front();
-    delete req;
-}
-
-const Message*
-RubyMemoryControl::peek()
-{
-    MemoryNode *node = peekNode();
-    Message* msg_ptr = node->m_msgptr.get();
-    assert(msg_ptr != NULL);
-    return msg_ptr;
-}
-
-MemoryNode *
-RubyMemoryControl::peekNode()
-{
-    assert(isReady());
-    MemoryNode *req = m_response_queue.front();
-    DPRINTF(RubyMemory, "Peek: memory request%7d: %#08x %c sched %c\n",
-            req->m_msg_counter, req->m_addr, req->m_is_mem_read ? 'R':'W',
-            m_event.scheduled() ? 'Y':'N');
-
-    return req;
-}
-
-bool
-RubyMemoryControl::isReady()
-{
-    return ((!m_response_queue.empty()) &&
-            (m_response_queue.front()->m_time <= g_system_ptr->curCycle()));
-}
-
-void
-RubyMemoryControl::setConsumer(Consumer* consumer_ptr)
-{
-    m_consumer_ptr = consumer_ptr;
-}
-
 void
 RubyMemoryControl::print(ostream& out) const
 {
@@ -380,15 +332,17 @@ void
 RubyMemoryControl::enqueueToDirectory(MemoryNode *req, Cycles latency)
 {
     Tick arrival_time = clockEdge(latency);
-    Cycles ruby_arrival_time = g_system_ptr->ticksToCycles(arrival_time);
-    req->m_time = ruby_arrival_time;
-    m_response_queue.push_back(req);
+    PacketPtr pkt = req->pkt;
+
+    // access already turned the packet into a response
+    assert(pkt->isResponse());
+
+    // queue the packet in the response queue to be sent out after
+    // the static latency has passed
+    port.schedTimingResp(pkt, arrival_time);
 
     DPRINTF(RubyMemory, "Enqueueing msg %#08x %c back to directory at %15d\n",
             req->m_addr, req->m_is_mem_read ? 'R':'W', arrival_time);
-
-    // schedule the wake up
-    m_consumer_ptr->scheduleEventAbsolute(arrival_time);
 }
 
 // getBank returns an integer that is unique for each
@@ -560,9 +514,8 @@ RubyMemoryControl::issueRequest(int bank)
             req->m_is_mem_read? 'R':'W',
             bank, m_event.scheduled() ? 'Y':'N');
 
-    if (req->m_msgptr) {  // don't enqueue L3 writebacks
-        enqueueToDirectory(req, Cycles(m_mem_ctl_latency + m_mem_fixed_delay));
-    }
+    enqueueToDirectory(req, Cycles(m_mem_ctl_latency + m_mem_fixed_delay));
+
     m_oldRequest[bank] = 0;
     markTfaw(rank);
     m_bankBusyCounter[bank] = m_bank_busy_time;
@@ -724,16 +677,16 @@ RubyMemoryControl::functionalRead(Packet *pkt)
 {
     for (std::list<MemoryNode *>::iterator it = m_input_queue.begin();
          it != m_input_queue.end(); ++it) {
-        Message* msg_ptr = (*it)->m_msgptr.get();
-        if (msg_ptr->functionalRead(pkt)) {
+        PacketPtr msg = (*it)->pkt;
+        if (pkt->checkFunctional(msg)) {
             return true;
         }
     }
 
     for (std::list<MemoryNode *>::iterator it = m_response_queue.begin();
          it != m_response_queue.end(); ++it) {
-        Message* msg_ptr = (*it)->m_msgptr.get();
-        if (msg_ptr->functionalRead(pkt)) {
+        PacketPtr msg = (*it)->pkt;
+        if (pkt->checkFunctional(msg)) {
             return true;
         }
     }
@@ -741,16 +694,14 @@ RubyMemoryControl::functionalRead(Packet *pkt)
     for (uint32_t bank = 0; bank < m_total_banks; ++bank) {
         for (std::list<MemoryNode *>::iterator it = m_bankQueues[bank].begin();
              it != m_bankQueues[bank].end(); ++it) {
-            Message* msg_ptr = (*it)->m_msgptr.get();
-            if (msg_ptr->functionalRead(pkt)) {
+            PacketPtr msg = (*it)->pkt;
+            if (pkt->checkFunctional(msg)) {
                 return true;
             }
         }
     }
 
-    m_ram->read(Address(pkt->getAddr()), pkt->getPtr<uint8_t>(true),
-                pkt->getSize());
-
+    functionalAccess(pkt);
     return true;
 }
 
@@ -769,16 +720,16 @@ RubyMemoryControl::functionalWrite(Packet *pkt)
 
     for (std::list<MemoryNode *>::iterator it = m_input_queue.begin();
          it != m_input_queue.end(); ++it) {
-        Message* msg_ptr = (*it)->m_msgptr.get();
-        if (msg_ptr->functionalWrite(pkt)) {
+        PacketPtr msg = (*it)->pkt;
+        if (pkt->checkFunctional(msg)) {
             num_functional_writes++;
         }
     }
 
     for (std::list<MemoryNode *>::iterator it = m_response_queue.begin();
          it != m_response_queue.end(); ++it) {
-        Message* msg_ptr = (*it)->m_msgptr.get();
-        if (msg_ptr->functionalWrite(pkt)) {
+        PacketPtr msg = (*it)->pkt;
+        if (pkt->checkFunctional(msg)) {
             num_functional_writes++;
         }
     }
@@ -786,17 +737,15 @@ RubyMemoryControl::functionalWrite(Packet *pkt)
     for (uint32_t bank = 0; bank < m_total_banks; ++bank) {
         for (std::list<MemoryNode *>::iterator it = m_bankQueues[bank].begin();
              it != m_bankQueues[bank].end(); ++it) {
-            Message* msg_ptr = (*it)->m_msgptr.get();
-            if (msg_ptr->functionalWrite(pkt)) {
+            PacketPtr msg = (*it)->pkt;
+            if (pkt->checkFunctional(msg)) {
                 num_functional_writes++;
             }
         }
     }
 
-    m_ram->write(Address(pkt->getAddr()), pkt->getPtr<uint8_t>(true),
-                 pkt->getSize());
+    functionalAccess(pkt);
     num_functional_writes++;
-
     return num_functional_writes;
 }
 
@@ -804,6 +753,7 @@ void
 RubyMemoryControl::regStats()
 {
     m_profiler_ptr->regStats();
+    AbstractMemory::regStats();
 }
 
 RubyMemoryControl *
@@ -811,3 +761,45 @@ RubyMemoryControlParams::create()
 {
     return new RubyMemoryControl(this);
 }
+
+RubyMemoryControl::MemoryPort::MemoryPort(const std::string& name,
+                                          RubyMemoryControl& _memory)
+    : QueuedSlavePort(name, &_memory, queue), queue(_memory, *this),
+      memory(_memory)
+{ }
+
+AddrRangeList
+RubyMemoryControl::MemoryPort::getAddrRanges() const
+{
+    AddrRangeList ranges;
+    ranges.push_back(memory.getAddrRange());
+    return ranges;
+}
+
+void
+RubyMemoryControl::MemoryPort::recvFunctional(PacketPtr pkt)
+{
+    pkt->pushLabel(memory.name());
+
+    if (!queue.checkFunctional(pkt)) {
+        // Default implementation of SimpleTimingPort::recvFunctional()
+        // calls recvAtomic() and throws away the latency; we can save a
+        // little here by just not calculating the latency.
+        memory.functionalWrite(pkt);
+    }
+
+    pkt->popLabel();
+}
+
+Tick
+RubyMemoryControl::MemoryPort::recvAtomic(PacketPtr pkt)
+{
+    panic("This controller does not support recv atomic!\n");
+}
+
+bool
+RubyMemoryControl::MemoryPort::recvTimingReq(PacketPtr pkt)
+{
+    // pass it to the memory controller
+    return memory.recvTimingReq(pkt);
+}
index dde6143c4f29a48409094401f12f21368a9bbe63..6b1ec1702b4f6e96f7994dbc4c706a8c6edc8f62 100644 (file)
 #include <list>
 #include <string>
 
+#include "mem/abstract_mem.hh"
 #include "mem/protocol/MemoryMsg.hh"
 #include "mem/ruby/common/Address.hh"
 #include "mem/ruby/common/Global.hh"
 #include "mem/ruby/profiler/MemCntrlProfiler.hh"
-#include "mem/ruby/structures/MemoryControl.hh"
-#include "mem/ruby/structures/MemoryVector.hh"
+#include "mem/ruby/structures/MemoryNode.hh"
 #include "mem/ruby/system/System.hh"
 #include "params/RubyMemoryControl.hh"
 
@@ -49,7 +49,7 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-class RubyMemoryControl : public MemoryControl
+class RubyMemoryControl : public AbstractMemory, public Consumer
 {
   public:
     typedef RubyMemoryControlParams Params;
@@ -59,22 +59,18 @@ class RubyMemoryControl : public MemoryControl
 
     ~RubyMemoryControl();
 
+    virtual BaseSlavePort& getSlavePort(const std::string& if_name,
+                                        PortID idx = InvalidPortID);
     unsigned int drain(DrainManager *dm);
-
     void wakeup();
 
-    void setConsumer(Consumer* consumer_ptr);
-    Consumer* getConsumer() { return m_consumer_ptr; };
     void setDescription(const std::string& name) { m_description = name; };
     std::string getDescription() { return m_description; };
 
     // Called from the directory:
-    void enqueue(const MsgPtr& message, Cycles latency);
+    bool recvTimingReq(PacketPtr pkt);
+    void recvFunctional(PacketPtr pkt);
     void enqueueMemRef(MemoryNode *memRef);
-    void dequeue();
-    const Message* peek();
-    MemoryNode *peekNode();
-    bool isReady();
     bool areNSlotsAvailable(int n) { return true; };  // infinite queue length
 
     void print(std::ostream& out) const;
@@ -108,8 +104,34 @@ class RubyMemoryControl : public MemoryControl
     RubyMemoryControl (const RubyMemoryControl& obj);
     RubyMemoryControl& operator=(const RubyMemoryControl& obj);
 
+  private:
+    // For now, make use of a queued slave port to avoid dealing with
+    // flow control for the responses being sent back
+    class MemoryPort : public QueuedSlavePort
+    {
+        SlavePacketQueue queue;
+        RubyMemoryControl& memory;
+
+      public:
+        MemoryPort(const std::string& name, RubyMemoryControl& _memory);
+
+      protected:
+        Tick recvAtomic(PacketPtr pkt);
+
+        void recvFunctional(PacketPtr pkt);
+
+        bool recvTimingReq(PacketPtr);
+
+        virtual AddrRangeList getAddrRanges() const;
+    };
+
+    /**
+     * Our incoming port, for a multi-ported controller add a crossbar
+     * in front of it
+     */
+    MemoryPort port;
+
     // data members
-    Consumer* m_consumer_ptr;  // Consumer to signal a wakeup()
     std::string m_description;
     int m_msg_counter;
 
@@ -163,8 +185,20 @@ class RubyMemoryControl : public MemoryControl
 
     MemCntrlProfiler* m_profiler_ptr;
 
-    // Actual physical memory.
-    MemoryVector* m_ram;
+    class MemCntrlEvent : public Event
+    {
+      public:
+        MemCntrlEvent(RubyMemoryControl* _mem_cntrl)
+        {
+            mem_cntrl = _mem_cntrl;
+        }
+      private:
+        void process() { mem_cntrl->wakeup(); }
+
+        RubyMemoryControl* mem_cntrl;
+    };
+
+    MemCntrlEvent m_event;
 };
 
 std::ostream& operator<<(std::ostream& out, const RubyMemoryControl& obj);
index f0828fb19af666571d8a260e000066196cab34f0..78f2d8dcbcfb8b6b88d5993789bc93e84055a3c9 100644 (file)
 #          Brad Beckmann
 
 from m5.params import *
-from m5.SimObject import SimObject
-from MemoryControl import MemoryControl
+from AbstractMemory import AbstractMemory
 
-class RubyMemoryControl(MemoryControl):
+class RubyMemoryControl(AbstractMemory):
     type = 'RubyMemoryControl'
     cxx_class = 'RubyMemoryControl'
     cxx_header = "mem/ruby/structures/RubyMemoryControl.hh"
-    version = Param.Int("");
 
     banks_per_rank = Param.Int(8, "");
     ranks_per_dimm = Param.Int(2, "");
@@ -53,3 +51,7 @@ class RubyMemoryControl(MemoryControl):
     tFaw = Param.Int(0, "");
     mem_random_arbitrate = Param.Int(0, "");
     mem_fixed_delay = Param.Cycles(0, "");
+
+    # single-ported on the system interface side, instantiate with a
+    # crossbar in front of the controller for multiple ports
+    port = SlavePort("Slave port")
index dee5769d3dee38f99e954ff492115b30dbc984aa..ed00d738220f69e5a4dfa9f95f7e776e49b3b17d 100644 (file)
@@ -35,14 +35,12 @@ if env['PROTOCOL'] == 'None':
 
 SimObject('Cache.py')
 SimObject('DirectoryMemory.py')
-SimObject('MemoryControl.py')
 SimObject('RubyMemoryControl.py')
 SimObject('RubyPrefetcher.py')
 SimObject('WireBuffer.py')
 
 Source('DirectoryMemory.cc')
 Source('CacheMemory.cc')
-Source('MemoryControl.cc')
 Source('WireBuffer.cc')
 Source('RubyMemoryControl.cc')
 Source('MemoryNode.cc')
index 0943fb3f6a9403fa76204c20e92bf258bdf55b5f..77bd9448d0182affd52177aad4aa5b64d981454a 100644 (file)
@@ -38,8 +38,8 @@ class RubySystem(ClockedObject):
         "insert random delays on message enqueue times");
     block_size_bytes = Param.UInt32(64,
         "default cache block size; must be a power of two");
-    mem_size = Param.MemorySize("total memory size of the system");
-    no_mem_vec = Param.Bool(False, "do not allocate Ruby's mem vector");
+    memory_size_bits = Param.UInt32(64,
+        "number of bits that a memory address requires");
 
     # Profiler related configuration variables
     hot_lines = Param.Bool(False, "")
index 6f64207dcc67763656515e1855460d09c90ba76f..b54924ba7c11bd5b55ccff6608826d9710130d53 100644 (file)
@@ -55,7 +55,7 @@ class RubyPort(MemObject):
 class RubyPortProxy(RubyPort):
     type = 'RubyPortProxy'
     cxx_header = "mem/ruby/system/RubyPortProxy.hh"
-    access_phys_mem = True
+    access_phys_mem = False
     
 class RubySequencer(RubyPort):
     type = 'RubySequencer'
index 8bcc874747c428f2f8742e47c389d29cdce59fa3..066cfae8710c9ddfa51b04fa02711732ca98fcb0 100644 (file)
@@ -47,7 +47,6 @@ int RubySystem::m_random_seed;
 bool RubySystem::m_randomization;
 uint32_t RubySystem::m_block_size_bytes;
 uint32_t RubySystem::m_block_size_bits;
-uint64_t RubySystem::m_memory_size_bytes;
 uint32_t RubySystem::m_memory_size_bits;
 
 RubySystem::RubySystem(const Params *p)
@@ -63,20 +62,7 @@ RubySystem::RubySystem(const Params *p)
     m_block_size_bytes = p->block_size_bytes;
     assert(isPowerOf2(m_block_size_bytes));
     m_block_size_bits = floorLog2(m_block_size_bytes);
-
-    m_memory_size_bytes = p->mem_size;
-    if (m_memory_size_bytes == 0) {
-        m_memory_size_bits = 0;
-    } else {
-        m_memory_size_bits = ceilLog2(m_memory_size_bytes);
-    }
-
-    if (p->no_mem_vec) {
-        m_mem_vec = NULL;
-    } else {
-        m_mem_vec = new MemoryVector;
-        m_mem_vec->resize(m_memory_size_bytes);
-    }
+    m_memory_size_bits = p->memory_size_bits;
 
     m_warmup_enabled = false;
     m_cooldown_enabled = false;
@@ -108,17 +94,10 @@ RubySystem::registerAbstractController(AbstractController* cntrl)
   g_abs_controls[id.getType()][id.getNum()] = cntrl;
 }
 
-void
-RubySystem::registerMemController(MemoryControl *mc) {
-    m_memory_controller_vec.push_back(mc);
-}
-
 RubySystem::~RubySystem()
 {
     delete m_network;
     delete m_profiler;
-    if (m_mem_vec)
-        delete m_mem_vec;
 }
 
 void
@@ -206,19 +185,8 @@ RubySystem::serialize(std::ostream &os)
     // Restore curTick
     setCurTick(curtick_original);
 
-    uint8_t *raw_data = NULL;
-    uint64 memory_trace_size = m_mem_vec->collatePages(raw_data);
-
-    string memory_trace_file = name() + ".memory.gz";
-    writeCompressedTrace(raw_data, memory_trace_file,
-                         memory_trace_size);
-
-    SERIALIZE_SCALAR(memory_trace_file);
-    SERIALIZE_SCALAR(memory_trace_size);
-
-
     // Aggergate the trace entries together into a single array
-    raw_data = new uint8_t[4096];
+    uint8_t *raw_data = new uint8_t[4096];
     uint64 cache_trace_size = m_cache_recorder->aggregateRecords(&raw_data,
                                                                  4096);
     string cache_trace_file = name() + ".cache.gz";
@@ -272,22 +240,6 @@ RubySystem::unserialize(Checkpoint *cp, const string &section)
     uint64 block_size_bytes = getBlockSizeBytes();
     UNSERIALIZE_OPT_SCALAR(block_size_bytes);
 
-    if (m_mem_vec != NULL) {
-        string memory_trace_file;
-        uint64 memory_trace_size = 0;
-
-        UNSERIALIZE_SCALAR(memory_trace_file);
-        UNSERIALIZE_SCALAR(memory_trace_size);
-        memory_trace_file = cp->cptDir + "/" + memory_trace_file;
-
-        readCompressedTrace(memory_trace_file, uncompressed_trace,
-                            memory_trace_size);
-        m_mem_vec->populatePages(uncompressed_trace);
-
-        delete [] uncompressed_trace;
-        uncompressed_trace = NULL;
-    }
-
     string cache_trace_file;
     uint64 cache_trace_size = 0;
 
@@ -355,12 +307,6 @@ RubySystem::startup()
         m_cache_recorder = NULL;
         m_warmup_enabled = false;
 
-        // reset DRAM so that it's not waiting for events on the old event
-        // queue
-        for (int i = 0; i < m_memory_controller_vec.size(); ++i) {
-            m_memory_controller_vec[i]->reset();
-        }
-
         // Restore eventq head
         eventq_head = eventq->replaceHead(eventq_head);
         // Restore curTick and Ruby System's clock
index 8193764dcab336e51d9db5d8b33e3cb5babafa93..81c6029c6242146a5ab9a2a8d9b0456b7df7c3d5 100644 (file)
@@ -39,8 +39,6 @@
 #include "base/output.hh"
 #include "mem/ruby/profiler/Profiler.hh"
 #include "mem/ruby/slicc_interface/AbstractController.hh"
-#include "mem/ruby/structures/MemoryControl.hh"
-#include "mem/ruby/structures/MemoryVector.hh"
 #include "mem/ruby/system/CacheRecorder.hh"
 #include "mem/packet.hh"
 #include "params/RubySystem.hh"
@@ -75,7 +73,6 @@ class RubySystem : public ClockedObject
     static int getRandomization() { return m_randomization; }
     static uint32_t getBlockSizeBytes() { return m_block_size_bytes; }
     static uint32_t getBlockSizeBits() { return m_block_size_bits; }
-    static uint64_t getMemorySizeBytes() { return m_memory_size_bytes; }
     static uint32_t getMemorySizeBits() { return m_memory_size_bits; }
 
     // Public Methods
@@ -86,13 +83,6 @@ class RubySystem : public ClockedObject
         return m_profiler;
     }
 
-    MemoryVector*
-    getMemoryVector()
-    {
-        assert(m_mem_vec != NULL);
-        return m_mem_vec;
-    }
-
     void regStats() { m_profiler->regStats(name()); }
     void collateStats() { m_profiler->collateStats(); }
     void resetStats();
@@ -106,7 +96,6 @@ class RubySystem : public ClockedObject
 
     void registerNetwork(Network*);
     void registerAbstractController(AbstractController*);
-    void registerMemController(MemoryControl *mc);
 
     bool eventQueueEmpty() { return eventq->empty(); }
     void enqueueRubyEvent(Tick tick)
@@ -132,16 +121,13 @@ class RubySystem : public ClockedObject
     static bool m_randomization;
     static uint32_t m_block_size_bytes;
     static uint32_t m_block_size_bits;
-    static uint64_t m_memory_size_bytes;
     static uint32_t m_memory_size_bits;
 
     Network* m_network;
-    std::vector<MemoryControl *> m_memory_controller_vec;
     std::vector<AbstractController *> m_abs_cntrl_vec;
 
   public:
     Profiler* m_profiler;
-    MemoryVector* m_mem_vec;
     bool m_warmup_enabled;
     bool m_cooldown_enabled;
     CacheRecorder* m_cache_recorder;
index 009680941394bc637b3f83ed6e5960b0a4c05b14..8b7a63f6afdebe563f23ea6c8ab518f23b5699b3 100644 (file)
@@ -285,7 +285,7 @@ class $c_ident : public AbstractController
     void recordCacheTrace(int cntrl, CacheRecorder* tr);
     Sequencer* getSequencer() const;
 
-    uint32_t functionalWriteBuffers(PacketPtr&);
+    int functionalWriteBuffers(PacketPtr&);
 
     void countTransition(${ident}_State state, ${ident}_Event event);
     void possibleTransition(${ident}_State state, ${ident}_Event event);
@@ -989,10 +989,10 @@ $c_ident::${{action.ident}}(const Address& addr)
 
         # Function for functional writes to messages buffered in the controller
         code('''
-uint32_t
+int
 $c_ident::functionalWriteBuffers(PacketPtr& pkt)
 {
-    uint32_t num_functional_writes = 0;
+    int num_functional_writes = 0;
 ''')
         for var in self.objects:
             vtype = var.type
index fed60ba468b4c5a5952130e619c578afd81dd57c..08b9ee69f8be1d6ab1589d2f55d0ed77fa37f74c 100644 (file)
@@ -106,7 +106,7 @@ connectPorts(SimObject *o1, const std::string &name1, int i1,
     ac1 = dynamic_cast<AbstractController*>(o1);
     ac2 = dynamic_cast<AbstractController*>(o2);
 
-    if (ac1 || ac2) {
+    if ((ac1 || ac2) && name1 != "memory" && name2 != "memory") {
         MessageBuffer *b = new MessageBuffer();
 
         // set the message buffer associated with the provided names
index badd64e63791d1c6f8f01528ad803248cff45a75..f71370c5ef66e0710af22b26b806b032387c0cc4 100644 (file)
@@ -80,7 +80,6 @@ options.num_cpus = nb_cores
 # system simulated
 system = System(cpu = cpus,
                 funcmem = SimpleMemory(in_addr_map = False),
-                physmem = SimpleMemory(null = True),
                 funcbus = NoncoherentXBar())
 # Dummy voltage domain for all our clock domains
 system.voltage_domain = VoltageDomain()
index 633a19e2fc6e26462fc6280c1bc80f40f2ec581c..782cda60df1fbe7973ef4d3d3cc2decc291e6f33 100644 (file)
@@ -91,8 +91,5 @@ for (i, cpu) in enumerate(system.cpu):
     cpu.interrupts.int_master = system.ruby._cpu_ports[i].slave
     cpu.interrupts.int_slave = system.ruby._cpu_ports[i].master
 
-system.physmem = [SimpleMemory(range = r, null = True)
-                  for r in system.mem_ranges]
-
 root = Root(full_system = True, system = system)
 m5.ticks.setGlobalFrequency('1THz')
index cbb5789383e19bc5ae7769e9282bab5553b59587..22334efb4cd18a5471285f526b36da58854baa88 100644 (file)
@@ -80,7 +80,7 @@ tester = RubyTester(check_flush = check_flush, checks_to_complete = 100,
 
 # We set the testers as cpu for ruby to find the correct clock domains
 # for the L1 Objects.
-system = System(cpu = tester, physmem = SimpleMemory(null = True))
+system = System(cpu = tester)
 
 # Dummy voltage domain for all our clock domains
 system.voltage_domain = VoltageDomain(voltage = options.sys_voltage)
index da7733acbf440985002f799c64f2f647cf1d6da1..263b330fb10345299d7c8ed1ba96932e58b63488 100644 (file)
@@ -71,8 +71,7 @@ cpus = [ TimingSimpleCPU(cpu_id=i) for i in xrange(nb_cores) ]
 options.num_cpus = nb_cores
 
 # system simulated
-system = System(cpu = cpus, physmem = SimpleMemory(),
-                clk_domain = SrcClockDomain(clock = '1GHz'))
+system = System(cpu = cpus, clk_domain = SrcClockDomain(clock = '1GHz'))
 
 # Create a seperate clock domain for components that should run at
 # CPUs frequency
index 3ce6266c1423fe0f1a0d7acce4f79822b5417966..b9fb650e5cf736d2b92c85c432b99d200165033d 100644 (file)
@@ -65,9 +65,9 @@ options.l3_assoc=2
 
 # this is a uniprocessor only test
 options.num_cpus = 1
-
 cpu = TimingSimpleCPU(cpu_id=0)
-system = System(cpu = cpu, physmem = SimpleMemory(null = True))
+system = System(cpu = cpu)
+
 # Dummy voltage domain for all our clock domains
 system.voltage_domain = VoltageDomain(voltage = options.sys_voltage)
 system.clk_domain = SrcClockDomain(clock = '1GHz',