config: separate function for instantiating a memory controller
[gem5.git] / configs / ruby / Ruby.py
index e9a8a3c3f67e84a9bbe76797d0143a121f88e1d4..3c43fa6c6ab7b2583830352c954a5cc2bd02d152 100644 (file)
@@ -43,6 +43,9 @@ import math
 import m5
 from m5.objects import *
 from m5.defines import buildEnv
+from m5.util import addToPath, fatal
+
+addToPath('../topologies')
 
 def define_options(parser):
     # By default, ruby uses the simple timing cpu
@@ -100,15 +103,41 @@ def create_topology(controllers, options):
 
 def create_system(options, system, piobus = None, dma_ports = []):
 
-    system.ruby = RubySystem(stats_filename = options.ruby_stats,
-                             no_mem_vec = options.use_map)
+    system.ruby = RubySystem(no_mem_vec = options.use_map)
     ruby = system.ruby
 
+    # Set the network classes based on the command line options
+    if options.garnet_network == "fixed":
+        NetworkClass = GarnetNetwork_d
+        IntLinkClass = GarnetIntLink_d
+        ExtLinkClass = GarnetExtLink_d
+        RouterClass = GarnetRouter_d
+        InterfaceClass = GarnetNetworkInterface_d
+
+    elif options.garnet_network == "flexible":
+        NetworkClass = GarnetNetwork
+        IntLinkClass = GarnetIntLink
+        ExtLinkClass = GarnetExtLink
+        RouterClass = GarnetRouter
+        InterfaceClass = GarnetNetworkInterface
+
+    else:
+        NetworkClass = SimpleNetwork
+        IntLinkClass = SimpleIntLink
+        ExtLinkClass = SimpleExtLink
+        RouterClass = Switch
+        InterfaceClass = None
+
+    # Instantiate the network object so that the controllers can connect to it.
+    network = NetworkClass(ruby_system = ruby, topology = options.topology,
+            routers = [], ext_links = [], int_links = [], netifs = [])
+    ruby.network = network
+
     protocol = buildEnv['PROTOCOL']
     exec "import %s" % protocol
     try:
         (cpu_sequencers, dir_cntrls, topology) = \
-             eval("%s.create_system(options, system, piobus, dma_ports, ruby)"
+             eval("%s.create_system(options, system, dma_ports, ruby)"
                   % protocol)
     except:
         print "Error: could not create sytem for ruby protocol %s" % protocol
@@ -118,6 +147,7 @@ def create_system(options, system, piobus = None, dma_ports = []):
     # independent of the protocol and kept in the protocol-agnostic
     # part (i.e. here).
     sys_port_proxy = RubyPortProxy(ruby_system = ruby)
+
     # Give the system port proxy a SimObject parent without creating a
     # full-fledged controller
     system.sys_port_proxy = sys_port_proxy
@@ -125,54 +155,27 @@ def create_system(options, system, piobus = None, dma_ports = []):
     # Connect the system port for loading of binaries etc
     system.system_port = system.sys_port_proxy.slave
 
+    # Create the network topology
+    topology.makeTopology(options, network, IntLinkClass, ExtLinkClass,
+            RouterClass)
 
-    #
-    # Set the network classes based on the command line options
-    #
-    if options.garnet_network == "fixed":
-        class NetworkClass(GarnetNetwork_d): pass
-        class IntLinkClass(GarnetIntLink_d): pass
-        class ExtLinkClass(GarnetExtLink_d): pass
-        class RouterClass(GarnetRouter_d): pass
-    elif options.garnet_network == "flexible":
-        class NetworkClass(GarnetNetwork): pass
-        class IntLinkClass(GarnetIntLink): pass
-        class ExtLinkClass(GarnetExtLink): pass
-        class RouterClass(GarnetRouter): pass
-    else:
-        class NetworkClass(SimpleNetwork): pass
-        class IntLinkClass(SimpleIntLink): pass
-        class ExtLinkClass(SimpleExtLink): pass
-        class RouterClass(Switch): pass
-
-    #
-    # Important: the topology must be instantiated before the network and after
-    # the controllers. Hence the separation between topology definition and
-    # instantiation.
-    #
-
-    routers, int_links, ext_links = topology.makeTopology(options,
-                                    IntLinkClass, ExtLinkClass, RouterClass)
-    network = NetworkClass(ruby_system = ruby, routers = routers,
-                           int_links = int_links, ext_links = ext_links,
-                           topology = topology.description)
+    if InterfaceClass != None:
+        netifs = [InterfaceClass(id=i) for (i,n) in enumerate(network.ext_links)]
+        network.netifs = netifs
 
     if options.network_fault_model:
         assert(options.garnet_network == "fixed")
         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')
 
-    dir_bits = int(math.log(options.num_dirs, 2))
     ruby.block_size_bytes = options.cacheline_size
     block_size_bits = int(math.log(options.cacheline_size, 2))
 
@@ -182,6 +185,7 @@ def create_system(options, system, piobus = None, dma_ports = []):
         # 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:
@@ -190,11 +194,17 @@ def create_system(options, system, piobus = None, dma_ports = []):
 
     phys_mem_size = sum(map(lambda r: r.size(), system.mem_ranges))
     assert(total_mem_size.value == phys_mem_size)
-
-    ruby_profiler = RubyProfiler(ruby_system = ruby,
-                                 num_of_sequencers = len(cpu_sequencers))
-    ruby.network = network
-    ruby.profiler = ruby_profiler
     ruby.mem_size = total_mem_size
-    ruby._cpu_ruby_ports = cpu_sequencers
+
+    # Connect the cpu sequencers and the piobus
+    if piobus != None:
+        for cpu_seq in cpu_sequencers:
+            cpu_seq.pio_master_port = piobus.slave
+            cpu_seq.mem_master_port = piobus.slave
+
+            if buildEnv['TARGET_ISA'] == "x86":
+                cpu_seq.pio_slave_port = piobus.master
+
+    ruby._cpu_ports = cpu_sequencers
+    ruby.num_of_sequencers = len(cpu_sequencers)
     ruby.random_seed    = options.random_seed