network: convert links & switches to first class C++ SimObjects
authorBrad Beckmann <Brad.Beckmann@amd.com>
Fri, 29 Apr 2011 00:18:14 +0000 (17:18 -0700)
committerBrad Beckmann <Brad.Beckmann@amd.com>
Fri, 29 Apr 2011 00:18:14 +0000 (17:18 -0700)
This patch converts links and switches from second class simobjects that were
virtually ignored by the networks (both simple and Garnet) to first class
simobjects that directly correspond to c++ ojbects manipulated by the
topology and network classes.  This is especially true for Garnet, where the
links and switches directly correspond to specific C++ objects.

By making this change, many aspects of the Topology class were simplified.

--HG--
rename : src/mem/ruby/network/Network.cc => src/mem/ruby/network/BasicLink.cc
rename : src/mem/ruby/network/Network.hh => src/mem/ruby/network/BasicLink.hh
rename : src/mem/ruby/network/Network.cc => src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.cc
rename : src/mem/ruby/network/Network.hh => src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.hh
rename : src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.py => src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.py
rename : src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.py => src/mem/ruby/network/garnet/fixed-pipeline/GarnetRouter_d.py
rename : src/mem/ruby/network/Network.cc => src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.cc
rename : src/mem/ruby/network/Network.hh => src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.hh
rename : src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.py => src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.py
rename : src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.py => src/mem/ruby/network/garnet/flexible-pipeline/GarnetRouter.py

50 files changed:
configs/ruby/MESI_CMP_directory.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/Network_test.py
configs/ruby/Ruby.py
src/mem/protocol/RubySlicc_Exports.sm
src/mem/ruby/network/BasicLink.cc [new file with mode: 0644]
src/mem/ruby/network/BasicLink.hh [new file with mode: 0644]
src/mem/ruby/network/BasicLink.py [new file with mode: 0644]
src/mem/ruby/network/BasicRouter.cc [new file with mode: 0644]
src/mem/ruby/network/BasicRouter.hh [new file with mode: 0644]
src/mem/ruby/network/BasicRouter.py [new file with mode: 0644]
src/mem/ruby/network/Network.hh
src/mem/ruby/network/Network.py
src/mem/ruby/network/SConscript
src/mem/ruby/network/Topology.cc
src/mem/ruby/network/Topology.hh
src/mem/ruby/network/garnet/fixed-pipeline/CreditLink_d.hh
src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.cc [new file with mode: 0644]
src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.hh [new file with mode: 0644]
src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.py [new file with mode: 0644]
src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc
src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh
src/mem/ruby/network/garnet/fixed-pipeline/GarnetRouter_d.py [new file with mode: 0644]
src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.cc
src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh
src/mem/ruby/network/garnet/fixed-pipeline/Router_d.cc
src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh
src/mem/ruby/network/garnet/fixed-pipeline/SConscript
src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.cc [new file with mode: 0644]
src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.hh [new file with mode: 0644]
src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.py [new file with mode: 0644]
src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc
src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.hh
src/mem/ruby/network/garnet/flexible-pipeline/GarnetRouter.py [new file with mode: 0644]
src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.cc
src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh
src/mem/ruby/network/garnet/flexible-pipeline/Router.cc
src/mem/ruby/network/garnet/flexible-pipeline/Router.hh
src/mem/ruby/network/garnet/flexible-pipeline/SConscript
src/mem/ruby/network/orion/NetworkPower.cc
src/mem/ruby/network/simple/SimpleNetwork.cc
src/mem/ruby/network/simple/SimpleNetwork.hh
src/mem/ruby/network/topologies/Crossbar.py
src/mem/ruby/network/topologies/Mesh.py
src/mem/ruby/network/topologies/MeshDirCorners.py
src/mem/ruby/slicc_interface/AbstractController.hh
src/mem/ruby/slicc_interface/Controller.py

index 2f7faab524a77f6187789fe210047e4dfdd7e50d..4bd969be57efdb82e1e4ba701c80ab3646c056f1 100644 (file)
@@ -71,6 +71,8 @@ def create_system(options, system, piobus, dma_devices):
     l2_bits = int(math.log(options.num_l2caches, 2))
     block_size_bits = int(math.log(options.cacheline_size, 2))
     
+    cntrl_count = 0
+    
     for i in xrange(options.num_cpus):
         #
         # First create the Ruby objects associated with this cpu
@@ -92,6 +94,7 @@ def create_system(options, system, piobus, dma_devices):
             cpu_seq.pio_port = piobus.port
 
         l1_cntrl = L1Cache_Controller(version = i,
+                                      cntrl_id = cntrl_count,
                                       sequencer = cpu_seq,
                                       L1IcacheMemory = l1i_cache,
                                       L1DcacheMemory = l1d_cache,
@@ -104,6 +107,8 @@ def create_system(options, system, piobus, dma_devices):
         #
         cpu_sequencers.append(cpu_seq)
         l1_cntrl_nodes.append(l1_cntrl)
+        
+        cntrl_count += 1
 
     l2_index_start = block_size_bits + l2_bits
 
@@ -116,11 +121,14 @@ def create_system(options, system, piobus, dma_devices):
                            start_index_bit = l2_index_start)
 
         l2_cntrl = L2Cache_Controller(version = i,
+                                      cntrl_id = cntrl_count,
                                       L2cacheMemory = l2_cache)
         
         exec("system.l2_cntrl%d = l2_cntrl" % i)
         l2_cntrl_nodes.append(l2_cntrl)
         
+        cntrl_count += 1
+        
     phys_mem_size = long(system.physmem.range.second) - \
                       long(system.physmem.range.first) + 1
     mem_module_size = phys_mem_size / options.num_dirs
@@ -136,6 +144,7 @@ def create_system(options, system, piobus, dma_devices):
         dir_size.value = mem_module_size
 
         dir_cntrl = Directory_Controller(version = i,
+                                         cntrl_id = cntrl_count,
                                          directory = \
                                          RubyDirectoryMemory(version = i,
                                                              size = \
@@ -145,6 +154,8 @@ def create_system(options, system, piobus, dma_devices):
         exec("system.dir_cntrl%d = dir_cntrl" % i)
         dir_cntrl_nodes.append(dir_cntrl)
 
+        cntrl_count += 1
+
     for i, dma_device in enumerate(dma_devices):
         #
         # Create the Ruby objects associated with the dma controller
@@ -154,6 +165,7 @@ def create_system(options, system, piobus, dma_devices):
                                physmem = system.physmem)
         
         dma_cntrl = DMA_Controller(version = i,
+                                   cntrl_id = cntrl_count,
                                    dma_sequencer = dma_seq)
 
         exec("system.dma_cntrl%d = dma_cntrl" % i)
@@ -163,6 +175,8 @@ def create_system(options, system, piobus, dma_devices):
             exec("system.dma_cntrl%d.dma_sequencer.port = dma_device.dma" % i)
         dma_cntrl_nodes.append(dma_cntrl)
 
+        cntrl_count += 1
+
     all_cntrls = l1_cntrl_nodes + \
                  l2_cntrl_nodes + \
                  dir_cntrl_nodes + \
index 062748eef85e5edb60c514d3835a2831c4addbbb..5f5703d4e014047c2b44858483873dc772692341 100644 (file)
@@ -62,6 +62,8 @@ def create_system(options, system, piobus, dma_devices):
     # controller constructors are called before the network constructor
     #
     block_size_bits = int(math.log(options.cacheline_size, 2))
+
+    cntrl_count = 0
     
     for i in xrange(options.num_cpus):
         #
@@ -86,6 +88,7 @@ def create_system(options, system, piobus, dma_devices):
             cpu_seq.pio_port = piobus.port
 
         l1_cntrl = L1Cache_Controller(version = i,
+                                      cntrl_id = cntrl_count,
                                       sequencer = cpu_seq,
                                       cacheMemory = cache)
 
@@ -96,6 +99,8 @@ def create_system(options, system, piobus, dma_devices):
         cpu_sequencers.append(cpu_seq)
         l1_cntrl_nodes.append(l1_cntrl)
 
+        cntrl_count += 1
+
     phys_mem_size = long(system.physmem.range.second) - \
                       long(system.physmem.range.first) + 1
     mem_module_size = phys_mem_size / options.num_dirs
@@ -111,6 +116,7 @@ def create_system(options, system, piobus, dma_devices):
         dir_size.value = mem_module_size
 
         dir_cntrl = Directory_Controller(version = i,
+                                         cntrl_id = cntrl_count,
                                          directory = \
                                          RubyDirectoryMemory( \
                                                     version = i,
@@ -123,6 +129,8 @@ def create_system(options, system, piobus, dma_devices):
         exec("system.dir_cntrl%d = dir_cntrl" % i)
         dir_cntrl_nodes.append(dir_cntrl)
 
+        cntrl_count += 1
+
     for i, dma_device in enumerate(dma_devices):
         #
         # Create the Ruby objects associated with the dma controller
@@ -132,6 +140,7 @@ def create_system(options, system, piobus, dma_devices):
                                physmem = system.physmem)
         
         dma_cntrl = DMA_Controller(version = i,
+                                   cntrl_id = cntrl_count,
                                    dma_sequencer = dma_seq)
 
         exec("system.dma_cntrl%d = dma_cntrl" % i)
@@ -142,6 +151,8 @@ def create_system(options, system, piobus, dma_devices):
         dma_cntrl.dma_sequencer.port = dma_device.dma
         dma_cntrl_nodes.append(dma_cntrl)
 
+        cntrl_count += 1
+
     all_cntrls = l1_cntrl_nodes + dir_cntrl_nodes + dma_cntrl_nodes
 
     return (cpu_sequencers, dir_cntrl_nodes, all_cntrls)
index ff7ea0cc5b68bc2ea54600e6491d4a55a93f8599..15558a62d682925776c429c5522bc5e9479f6c33 100644 (file)
@@ -70,6 +70,8 @@ def create_system(options, system, piobus, dma_devices):
     #
     l2_bits = int(math.log(options.num_l2caches, 2))
     block_size_bits = int(math.log(options.cacheline_size, 2))
+
+    cntrl_count = 0
     
     for i in xrange(options.num_cpus):
         #
@@ -92,6 +94,7 @@ def create_system(options, system, piobus, dma_devices):
             cpu_seq.pio_port = piobus.port
 
         l1_cntrl = L1Cache_Controller(version = i,
+                                      cntrl_id = cntrl_count,
                                       sequencer = cpu_seq,
                                       L1IcacheMemory = l1i_cache,
                                       L1DcacheMemory = l1d_cache,
@@ -104,6 +107,8 @@ def create_system(options, system, piobus, dma_devices):
         cpu_sequencers.append(cpu_seq)
         l1_cntrl_nodes.append(l1_cntrl)
 
+        cntrl_count += 1
+
     l2_index_start = block_size_bits + l2_bits
 
     for i in xrange(options.num_l2caches):
@@ -115,10 +120,13 @@ def create_system(options, system, piobus, dma_devices):
                            start_index_bit = l2_index_start)
 
         l2_cntrl = L2Cache_Controller(version = i,
+                                      cntrl_id = cntrl_count,
                                       L2cacheMemory = l2_cache)
         
         exec("system.l2_cntrl%d = l2_cntrl" % i)
         l2_cntrl_nodes.append(l2_cntrl)
+
+        cntrl_count += 1
         
     phys_mem_size = long(system.physmem.range.second) - \
                       long(system.physmem.range.first) + 1
@@ -135,6 +143,7 @@ def create_system(options, system, piobus, dma_devices):
         dir_size.value = mem_module_size
 
         dir_cntrl = Directory_Controller(version = i,
+                                         cntrl_id = cntrl_count,
                                          directory = \
                                          RubyDirectoryMemory(version = i,
                                                              size = \
@@ -144,6 +153,8 @@ def create_system(options, system, piobus, dma_devices):
         exec("system.dir_cntrl%d = dir_cntrl" % i)
         dir_cntrl_nodes.append(dir_cntrl)
 
+        cntrl_count += 1
+
     for i, dma_device in enumerate(dma_devices):
         #
         # Create the Ruby objects associated with the dma controller
@@ -153,6 +164,7 @@ def create_system(options, system, piobus, dma_devices):
                                physmem = system.physmem)
         
         dma_cntrl = DMA_Controller(version = i,
+                                   cntrl_id = cntrl_count,
                                    dma_sequencer = dma_seq)
 
         exec("system.dma_cntrl%d = dma_cntrl" % i)
@@ -162,6 +174,8 @@ def create_system(options, system, piobus, dma_devices):
             exec("system.dma_cntrl%d.dma_sequencer.port = dma_device.dma" % i)
         dma_cntrl_nodes.append(dma_cntrl)
 
+        cntrl_count += 1
+
     all_cntrls = l1_cntrl_nodes + \
                  l2_cntrl_nodes + \
                  dir_cntrl_nodes + \
index 72721058bad5ae1c8952bf6197036fc3c83e3b5f..5b6e21f33a17e9b19c962f082529604de9f134bb 100644 (file)
@@ -84,6 +84,8 @@ def create_system(options, system, piobus, dma_devices):
     l2_bits = int(math.log(options.num_l2caches, 2))
     block_size_bits = int(math.log(options.cacheline_size, 2))
     
+    cntrl_count = 0
+
     for i in xrange(options.num_cpus):
         #
         # First create the Ruby objects associated with this cpu
@@ -105,6 +107,7 @@ def create_system(options, system, piobus, dma_devices):
             cpu_seq.pio_port = piobus.port
 
         l1_cntrl = L1Cache_Controller(version = i,
+                                      cntrl_id = cntrl_count,
                                       sequencer = cpu_seq,
                                       L1IcacheMemory = l1i_cache,
                                       L1DcacheMemory = l1d_cache,
@@ -126,6 +129,8 @@ def create_system(options, system, piobus, dma_devices):
         cpu_sequencers.append(cpu_seq)
         l1_cntrl_nodes.append(l1_cntrl)
 
+        cntrl_count += 1
+
     l2_index_start = block_size_bits + l2_bits
 
     for i in xrange(options.num_l2caches):
@@ -137,11 +142,14 @@ def create_system(options, system, piobus, dma_devices):
                            start_index_bit = l2_index_start)
 
         l2_cntrl = L2Cache_Controller(version = i,
+                                      cntrl_id = cntrl_count,
                                       L2cacheMemory = l2_cache,
                                       N_tokens = n_tokens)
         
         exec("system.l2_cntrl%d = l2_cntrl" % i)
         l2_cntrl_nodes.append(l2_cntrl)
+
+        cntrl_count += 1
         
     phys_mem_size = long(system.physmem.range.second) - \
                       long(system.physmem.range.first) + 1
@@ -158,6 +166,7 @@ def create_system(options, system, piobus, dma_devices):
         dir_size.value = mem_module_size
 
         dir_cntrl = Directory_Controller(version = i,
+                                         cntrl_id = cntrl_count,
                                          directory = \
                                          RubyDirectoryMemory(version = i,
                                                              size = \
@@ -168,6 +177,8 @@ def create_system(options, system, piobus, dma_devices):
         exec("system.dir_cntrl%d = dir_cntrl" % i)
         dir_cntrl_nodes.append(dir_cntrl)
 
+        cntrl_count += 1
+
     for i, dma_device in enumerate(dma_devices):
         #
         # Create the Ruby objects associated with the dma controller
@@ -177,6 +188,7 @@ def create_system(options, system, piobus, dma_devices):
                                physmem = system.physmem)
         
         dma_cntrl = DMA_Controller(version = i,
+                                   cntrl_id = cntrl_count,
                                    dma_sequencer = dma_seq)
 
         exec("system.dma_cntrl%d = dma_cntrl" % i)
@@ -186,6 +198,8 @@ def create_system(options, system, piobus, dma_devices):
             exec("system.dma_cntrl%d.dma_sequencer.port = dma_device.dma" % i)
         dma_cntrl_nodes.append(dma_cntrl)
 
+        cntrl_count += 1
+
     all_cntrls = l1_cntrl_nodes + \
                  l2_cntrl_nodes + \
                  dir_cntrl_nodes + \
index 3804a58b1651c54db81b84463342dd4b392234dd..4a03912646c61d7000717549c5267257729c4667 100644 (file)
@@ -79,6 +79,8 @@ def create_system(options, system, piobus, dma_devices):
     # controller constructors are called before the network constructor
     #
     block_size_bits = int(math.log(options.cacheline_size, 2))
+
+    cntrl_count = 0
     
     for i in xrange(options.num_cpus):
         #
@@ -104,6 +106,7 @@ def create_system(options, system, piobus, dma_devices):
             cpu_seq.pio_port = piobus.port
 
         l1_cntrl = L1Cache_Controller(version = i,
+                                      cntrl_id = cntrl_count,
                                       sequencer = cpu_seq,
                                       L1IcacheMemory = l1i_cache,
                                       L1DcacheMemory = l1d_cache,
@@ -121,6 +124,8 @@ def create_system(options, system, piobus, dma_devices):
         cpu_sequencers.append(cpu_seq)
         l1_cntrl_nodes.append(l1_cntrl)
 
+        cntrl_count += 1
+
     phys_mem_size = long(system.physmem.range.second) - \
                       long(system.physmem.range.first) + 1
     mem_module_size = phys_mem_size / options.num_dirs
@@ -162,6 +167,7 @@ def create_system(options, system, piobus, dma_devices):
                          start_index_bit = pf_start_bit)
 
         dir_cntrl = Directory_Controller(version = i,
+                                         cntrl_id = cntrl_count,
                                          directory = \
                                          RubyDirectoryMemory( \
                                                     version = i,
@@ -182,6 +188,8 @@ def create_system(options, system, piobus, dma_devices):
         exec("system.dir_cntrl%d = dir_cntrl" % i)
         dir_cntrl_nodes.append(dir_cntrl)
 
+        cntrl_count += 1
+
     for i, dma_device in enumerate(dma_devices):
         #
         # Create the Ruby objects associated with the dma controller
@@ -191,6 +199,7 @@ def create_system(options, system, piobus, dma_devices):
                                physmem = system.physmem)
         
         dma_cntrl = DMA_Controller(version = i,
+                                   cntrl_id = cntrl_count,
                                    dma_sequencer = dma_seq)
 
         exec("system.dma_cntrl%d = dma_cntrl" % i)
@@ -203,6 +212,8 @@ def create_system(options, system, piobus, dma_devices):
         if options.recycle_latency:
             dma_cntrl.recycle_latency = options.recycle_latency
 
+        cntrl_count += 1
+
     all_cntrls = l1_cntrl_nodes + dir_cntrl_nodes + dma_cntrl_nodes
 
     return (cpu_sequencers, dir_cntrl_nodes, all_cntrls)
index fe1559f53ab46141f66f729cb0fbd69875e4384a..75ec9099ef311944940eb326e0fdf79999e15fbb 100644 (file)
@@ -69,6 +69,8 @@ def create_system(options, system, piobus, dma_devices):
     # controller constructors are called before the network constructor
     #
 
+    cntrl_count = 0
+
     for i in xrange(options.num_cpus):
         #
         # First create the Ruby objects associated with this cpu
@@ -91,6 +93,7 @@ def create_system(options, system, piobus, dma_devices):
             cpu_seq.pio_port = piobus.port
 
         l1_cntrl = L1Cache_Controller(version = i,
+                                      cntrl_id = cntrl_count,
                                       sequencer = cpu_seq,
                                       cacheMemory = cache)
 
@@ -101,6 +104,8 @@ def create_system(options, system, piobus, dma_devices):
         cpu_sequencers.append(cpu_seq)
         l1_cntrl_nodes.append(l1_cntrl)
 
+        cntrl_count += 1
+
     phys_mem_size = long(system.physmem.range.second) - \
                       long(system.physmem.range.first) + 1
     mem_module_size = phys_mem_size / options.num_dirs
@@ -116,6 +121,7 @@ def create_system(options, system, piobus, dma_devices):
         dir_size.value = mem_module_size
 
         dir_cntrl = Directory_Controller(version = i,
+                                         cntrl_id = cntrl_count,
                                          directory = \
                                          RubyDirectoryMemory(version = i,
                                                              size = dir_size),
@@ -124,6 +130,8 @@ def create_system(options, system, piobus, dma_devices):
         exec("system.dir_cntrl%d = dir_cntrl" % i)
         dir_cntrl_nodes.append(dir_cntrl)
 
+        cntrl_count += 1
+
     all_cntrls = l1_cntrl_nodes + dir_cntrl_nodes
 
     return (cpu_sequencers, dir_cntrl_nodes, all_cntrls)
index e5d3c4a7c4671d9126132c6d318ebb578be5840e..7f32829d6db2b55d0241d3e68193d4459ce50fff 100644 (file)
@@ -71,25 +71,41 @@ def create_system(options, system, piobus = None, dma_devices = []):
     except:
         print "Error: could not create sytem for ruby protocol %s" % protocol
         raise
-        
+
+    #
+    # 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(BasicIntLink): pass
+        class ExtLinkClass(BasicExtLink): pass
+        class RouterClass(BasicRouter): pass
+    
     #
     # Important: the topology must be created before the network and after the
     # controllers.
     #
     exec "import %s" % options.topology
     try:
-        net_topology = eval("%s.makeTopology(all_cntrls, options)" \
+        net_topology = eval("%s.makeTopology(all_cntrls, options, \
+                                             IntLinkClass, ExtLinkClass, \
+                                             RouterClass)" \
                             % options.topology)
     except:
         print "Error: could not create topology %s" % options.topology
         raise
-        
-    if options.garnet_network == "fixed":
-        network = GarnetNetwork_d(topology = net_topology)
-    elif options.garnet_network == "flexible":
-        network = GarnetNetwork(topology = net_topology)
-    else:
-        network = SimpleNetwork(topology = net_topology)
+
+    network = NetworkClass(topology = net_topology)
 
     #
     # Loop through the directory controlers.
index 5fb5f991237e0cf7618bdd8ab98aa1016fe63bb9..ccd3aeb7f243ab99b9e9759af8c046f0f00ef61b 100644 (file)
@@ -323,3 +323,9 @@ enumeration(RequestStatus, desc="...", default="RequestStatus_NULL")  {
   Aliased, desc="This request aliased with a currently outstanding request";
   NULL, desc="";
 }
+
+// LinkDirection
+enumeration(LinkDirection, desc="...") {
+  In, desc="Inward link direction";
+  Out, desc="Outward link direction";
+}
diff --git a/src/mem/ruby/network/BasicLink.cc b/src/mem/ruby/network/BasicLink.cc
new file mode 100644 (file)
index 0000000..907a04f
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2011 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 "mem/ruby/network/BasicLink.hh"
+
+BasicLink::BasicLink(const Params *p)
+    : SimObject(p)
+{
+    m_latency = p->latency;
+    m_bw_multiplier = p->bw_multiplier;
+    m_weight = p->weight;
+}
+
+void
+BasicLink::init()
+{
+}
+
+void
+BasicLink::print(std::ostream& out) const
+{
+    out << name();
+}
+
+BasicLink *
+BasicLinkParams::create()
+{
+    return new BasicLink(this);
+}
+
+BasicExtLink::BasicExtLink(const Params *p)
+    : BasicLink(p)
+{
+    m_int_node = p->int_node;
+    m_ext_node = p->ext_node;
+}
+
+BasicExtLink *
+BasicExtLinkParams::create()
+{
+    return new BasicExtLink(this);
+}
+
+BasicIntLink::BasicIntLink(const Params *p)
+    : BasicLink(p)
+{
+    m_node_a = p->node_a;
+    m_node_b = p->node_b;
+}
+
+BasicIntLink *
+BasicIntLinkParams::create()
+{
+    return new BasicIntLink(this);
+}
diff --git a/src/mem/ruby/network/BasicLink.hh b/src/mem/ruby/network/BasicLink.hh
new file mode 100644 (file)
index 0000000..c735980
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2011 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_NETWORK_BASIC_LINK_HH__
+#define __MEM_RUBY_NETWORK_BASIC_LINK_HH__
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include "params/BasicExtLink.hh"
+#include "params/BasicIntLink.hh"
+#include "params/BasicLink.hh"
+#include "mem/ruby/network/BasicRouter.hh"
+#include "mem/ruby/network/Topology.hh"
+#include "mem/ruby/slicc_interface/AbstractController.hh"
+#include "sim/sim_object.hh"
+
+class BasicLink : public SimObject
+{
+  public:
+    typedef BasicLinkParams Params;
+    BasicLink(const Params *p);
+    const Params *params() const { return (const Params *)_params; }
+
+    void init();
+
+    void print(std::ostream& out) const;
+
+    int m_latency;
+    int m_bw_multiplier;
+    int m_weight;
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, const BasicLink& obj)
+{
+    obj.print(out);
+    out << std::flush;
+    return out;
+}
+
+class BasicExtLink : public BasicLink
+{
+  public:
+    typedef BasicExtLinkParams Params;
+    BasicExtLink(const Params *p);
+    const Params *params() const { return (const Params *)_params; }
+
+    friend class Topology;
+
+  protected:
+    BasicRouter* m_int_node;
+    AbstractController* m_ext_node;
+};
+
+class BasicIntLink : public BasicLink
+{
+  public:
+    typedef BasicIntLinkParams Params;
+    BasicIntLink(const Params *p);
+    const Params *params() const { return (const Params *)_params; }
+
+    friend class Topology;
+
+  protected:
+    BasicRouter* m_node_a;
+    BasicRouter* m_node_b;
+};
+
+#endif // __MEM_RUBY_NETWORK_BASIC_LINK_HH__
diff --git a/src/mem/ruby/network/BasicLink.py b/src/mem/ruby/network/BasicLink.py
new file mode 100644 (file)
index 0000000..53df4d5
--- /dev/null
@@ -0,0 +1,50 @@
+# Copyright (c) 2011 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 m5.SimObject import SimObject
+
+class BasicLink(SimObject):
+    type = 'BasicLink'
+    link_id = Param.Int("ID in relation to other links")
+    latency = Param.Int(1, "latency")
+    bw_multiplier = Param.Int("simple network bw constant, usually in bytes")
+    weight = Param.Int(1, "used to restrict routing in shortest path analysis")
+
+class BasicExtLink(BasicLink):
+    type = 'BasicExtLink'
+    ext_node = Param.RubyController("External node")
+    int_node = Param.BasicRouter("ID of internal node")
+    bw_multiplier = 64
+
+class BasicIntLink(BasicLink):
+    type = 'BasicIntLink'
+    node_a = Param.BasicRouter("Router on one end")
+    node_b = Param.BasicRouter("Router on other end")
+    bw_multiplier = 16
diff --git a/src/mem/ruby/network/BasicRouter.cc b/src/mem/ruby/network/BasicRouter.cc
new file mode 100644 (file)
index 0000000..a6972af
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2011 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 "mem/ruby/network/BasicRouter.hh"
+
+BasicRouter::BasicRouter(const Params *p)
+    : SimObject(p)
+{
+    m_id = p->router_id;
+}
+
+void
+BasicRouter::init()
+{
+}
+
+void
+BasicRouter::print(std::ostream& out) const
+{
+    out << name();
+}
+
+BasicRouter *
+BasicRouterParams::create()
+{
+    return new BasicRouter(this);
+}
diff --git a/src/mem/ruby/network/BasicRouter.hh b/src/mem/ruby/network/BasicRouter.hh
new file mode 100644 (file)
index 0000000..67dc21c
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2011 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_NETWORK_BASIC_ROUTER_HH__
+#define __MEM_RUBY_NETWORK_BASIC_ROUTER_HH__
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include "params/BasicRouter.hh"
+#include "sim/sim_object.hh"
+
+class BasicRouter : public SimObject
+{
+  public:
+    typedef BasicRouterParams Params;
+    BasicRouter(const Params *p);
+    const Params *params() const { return (const Params *)_params; }
+
+    void init();
+
+    void print(std::ostream& out) const;
+
+    friend class Topology;
+
+  protected:
+    //
+    // ID in relation to other routers in the system
+    //
+    int m_id;
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, const BasicRouter& obj)
+{
+    obj.print(out);
+    out << std::flush;
+    return out;
+}
+
+#endif // __MEM_RUBY_NETWORK_BASIC_ROUTER_HH__
diff --git a/src/mem/ruby/network/BasicRouter.py b/src/mem/ruby/network/BasicRouter.py
new file mode 100644 (file)
index 0000000..0ff41c3
--- /dev/null
@@ -0,0 +1,35 @@
+# Copyright (c) 2011 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 m5.SimObject import SimObject
+
+class BasicRouter(SimObject):
+    type = 'BasicRouter'
+    router_id = Param.Int("ID in relation to other routers")
index 51be0105c3fdf62ba9426b545e46bd81334d4657..a33360e6add97b8a3d95197d6a171f634b80ec7c 100644 (file)
@@ -44,6 +44,7 @@
 #include <string>
 #include <vector>
 
+#include "mem/protocol/LinkDirection.hh"
 #include "mem/protocol/MessageSizeType.hh"
 #include "mem/ruby/common/Global.hh"
 #include "mem/ruby/system/NodeID.hh"
@@ -80,15 +81,18 @@ class Network : public SimObject
     virtual const std::vector<Throttle*>* getThrottles(NodeID id) const;
     virtual int getNumNodes() {return 1;}
 
-    virtual void makeOutLink(SwitchID src, NodeID dest,
-        const NetDest& routing_table_entry, int link_latency, int link_weight,
-        int bw_multiplier, bool isReconfiguration) = 0;
-    virtual void makeInLink(SwitchID src, NodeID dest,
-        const NetDest& routing_table_entry, int link_latency,
-        int bw_multiplier, bool isReconfiguration) = 0;
-    virtual void makeInternalLink(SwitchID src, NodeID dest,
-        const NetDest& routing_table_entry, int link_latency, int link_weight,
-        int bw_multiplier, bool isReconfiguration) = 0;
+    virtual void makeOutLink(SwitchID src, NodeID dest, BasicLink* link,
+                             LinkDirection direction,
+                             const NetDest& routing_table_entry,
+                             bool isReconfiguration) = 0;
+    virtual void makeInLink(NodeID src, SwitchID dest, BasicLink* link,
+                            LinkDirection direction,
+                            const NetDest& routing_table_entry, 
+                            bool isReconfiguration) = 0;
+    virtual void makeInternalLink(SwitchID src, SwitchID dest, BasicLink* link,
+                                  LinkDirection direction,
+                                  const NetDest& routing_table_entry,
+                                  bool isReconfiguration) = 0;
 
     virtual void reset() = 0;
 
index 530afcc456a84f3c94f85dae1c23013cf6935032..c539f7191d5471a6304e9356dd862a7cbad839cf 100644 (file)
 
 from m5.params import *
 from m5.SimObject import SimObject
-
-class Link(SimObject):
-    type = 'Link'
-    latency = Param.Int(1, "")
-    bw_multiplier = Param.Int("")
-    weight = Param.Int(1, "")
-
-class ExtLink(Link):
-    type = 'ExtLink'
-    ext_node = Param.RubyController("External node")
-    int_node = Param.Int("ID of internal node")
-    bw_multiplier = 64
-
-class IntLink(Link):
-    type = 'IntLink'
-    node_a = Param.Int("ID of internal node on one end")
-    node_b = Param.Int("ID of internal node on other end")
-    bw_multiplier = 16
+from BasicLink import BasicLink
 
 class Topology(SimObject):
     type = 'Topology'
     description = Param.String("Not Specified",
                                "the name of the imported topology module")
-    ext_links = VectorParam.ExtLink("Links to external nodes")
-    int_links = VectorParam.IntLink("Links between internal nodes")
-    num_int_nodes = Param.Int("Nunber of internal nodes")
+    ext_links = VectorParam.BasicExtLink("Links to external nodes")
+    int_links = VectorParam.BasicIntLink("Links between internal nodes")
+    routers = VectorParam.BasicRouter("Network routers")
     print_config = Param.Bool(False,
         "display topology config in the stats file")
 
index 079ecf9f687ade43d75d2d5cdb2822372ca92c4c..3c3bcea064c68db0501d664a580e3f8d317397ae 100644 (file)
@@ -33,7 +33,11 @@ Import('*')
 if not env['RUBY']:
     Return()
 
+SimObject('BasicLink.py')
+SimObject('BasicRouter.py')
 SimObject('Network.py')
 
+Source('BasicLink.cc')
+Source('BasicRouter.cc')
 Source('Network.cc')
 Source('Topology.cc')
index 61f3ad361693ae7db5e3dfd0e2dbd823a5f01255..58af3811f3422f9d6849be13fafa8d6ad78df93e 100644 (file)
@@ -33,6 +33,8 @@
 #include "mem/protocol/Protocol.hh"
 #include "mem/protocol/TopologyType.hh"
 #include "mem/ruby/common/NetDest.hh"
+#include "mem/ruby/network/BasicLink.hh"
+#include "mem/ruby/network/BasicRouter.hh"
 #include "mem/ruby/network/Network.hh"
 #include "mem/ruby/network/Topology.hh"
 #include "mem/ruby/slicc_interface/AbstractController.hh"
@@ -41,7 +43,8 @@
 using namespace std;
 
 const int INFINITE_LATENCY = 10000; // Yes, this is a big hack
-const int DEFAULT_BW_MULTIPLIER = 1;  // Just to be consistent with above :)
+
+class BasicRouter;
 
 // Note: In this file, we use the first 2*m_nodes SwitchIDs to
 // represent the input and output endpoint links.  These really are
@@ -64,7 +67,8 @@ Topology::Topology(const Params *p)
     : SimObject(p)
 {
     m_print_config = p->print_config;
-    m_number_of_switches = p->num_int_nodes;
+    m_number_of_switches = p->routers.size();
+
     // initialize component latencies record
     m_component_latencies.resize(0);
     m_component_inter_switches.resize(0);
@@ -77,47 +81,68 @@ Topology::Topology(const Params *p)
     if (m_nodes != params()->ext_links.size() &&
         m_nodes != params()->ext_links.size()) {
         fatal("m_nodes (%d) != ext_links vector length (%d)\n",
-            m_nodes != params()->ext_links.size());
+              m_nodes != params()->ext_links.size());
     }
 
-    // First create the links between the endpoints (i.e. controllers)
-    // and the network.
-    for (vector<ExtLink*>::const_iterator i = params()->ext_links.begin();
+    // analyze both the internal and external links, create data structures
+    // Note that the python created links are bi-directional, but that the
+    // topology and networks utilize uni-directional links.  Thus each 
+    // BasicLink is converted to two calls to add link, on for each direction
+    for (vector<BasicExtLink*>::const_iterator i = params()->ext_links.begin();
          i != params()->ext_links.end(); ++i) {
-        const ExtLinkParams *p = (*i)->params();
-        AbstractController *c = p->ext_node;
+        BasicExtLink *ext_link = (*i);
+        AbstractController *abs_cntrl = ext_link->params()->ext_node;
+        BasicRouter *router = ext_link->params()->int_node;
 
-        // Store the controller pointers for later
-        m_controller_vector.push_back(c);
+        // Store the controller and ExtLink pointers for later
+        m_controller_vector.push_back(abs_cntrl);
+        m_ext_link_vector.push_back(ext_link);
 
-        int ext_idx1 =
-            MachineType_base_number(c->getMachineType()) + c->getVersion();
+        int ext_idx1 = abs_cntrl->params()->cntrl_id;
         int ext_idx2 = ext_idx1 + m_nodes;
-        int int_idx = p->int_node + 2*m_nodes;
+        int int_idx = router->params()->router_id + 2*m_nodes;
 
-        // create the links in both directions
-        addLink(ext_idx1, int_idx, p->latency, p->bw_multiplier, p->weight);
-        addLink(int_idx, ext_idx2, p->latency, p->bw_multiplier, p->weight);
+        // create the internal uni-directional links in both directions
+        //   the first direction is marked: In
+        addLink(ext_idx1, int_idx, ext_link, LinkDirection_In);
+        //   the first direction is marked: Out
+        addLink(int_idx, ext_idx2, ext_link, LinkDirection_Out);
     }
 
-    for (vector<IntLink*>::const_iterator i = params()->int_links.begin();
+    for (vector<BasicIntLink*>::const_iterator i = params()->int_links.begin();
          i != params()->int_links.end(); ++i) {
-        const IntLinkParams *p = (*i)->params();
-        int a = p->node_a + 2*m_nodes;
-        int b = p->node_b + 2*m_nodes;
+        BasicIntLink *int_link = (*i);
+        BasicRouter *router_a = int_link->params()->node_a;
+        BasicRouter *router_b = int_link->params()->node_b;
+
+        // Store the IntLink pointers for later
+        m_int_link_vector.push_back(int_link);
 
-        // create the links in both directions
-        addLink(a, b, p->latency, p->bw_multiplier, p->weight);
-        addLink(b, a, p->latency, p->bw_multiplier, p->weight);
+        int a = router_a->params()->router_id + 2*m_nodes;
+        int b = router_b->params()->router_id + 2*m_nodes;
+
+        // create the internal uni-directional links in both directions
+        //   the first direction is marked: In
+        addLink(a, b, int_link, LinkDirection_In);
+        //   the second direction is marked: Out
+        addLink(b, a, int_link, LinkDirection_Out);
     }
 }
 
+void
+Topology::init()
+{
+}
+
 
 void
 Topology::initNetworkPtr(Network* net_ptr)
 {
-    for (int cntrl = 0; cntrl < m_controller_vector.size(); cntrl++) {
-        m_controller_vector[cntrl]->initNetworkPtr(net_ptr);
+    for (vector<BasicExtLink*>::const_iterator i = params()->ext_links.begin();
+         i != params()->ext_links.end(); ++i) {
+        BasicExtLink *ext_link = (*i);
+        AbstractController *abs_cntrl = ext_link->params()->ext_node;
+        abs_cntrl->initNetworkPtr(net_ptr);
     }
 }
 
@@ -126,41 +151,29 @@ Topology::createLinks(Network *net, bool isReconfiguration)
 {
     // Find maximum switchID
     SwitchID max_switch_id = 0;
-    for (int i = 0; i < m_links_src_vector.size(); i++) {
-        max_switch_id = max(max_switch_id, m_links_src_vector[i]);
-        max_switch_id = max(max_switch_id, m_links_dest_vector[i]);
+    for (LinkMap::const_iterator i = m_link_map.begin();
+         i != m_link_map.end(); ++i) {
+        std::pair<int, int> src_dest = (*i).first;
+        max_switch_id = max(max_switch_id, src_dest.first);
+        max_switch_id = max(max_switch_id, src_dest.second);        
     }
 
-    // Initialize weight vector
+    // Initialize weight, latency, and inter switched vectors
     Matrix topology_weights;
-    Matrix topology_latency;
-    Matrix topology_bw_multis;
     int num_switches = max_switch_id+1;
     topology_weights.resize(num_switches);
-    topology_latency.resize(num_switches);
-    topology_bw_multis.resize(num_switches);
-
-    // FIXME setting the size of a member variable here is a HACK!
     m_component_latencies.resize(num_switches);
-
-    // FIXME setting the size of a member variable here is a HACK!
     m_component_inter_switches.resize(num_switches);
 
     for (int i = 0; i < topology_weights.size(); i++) {
         topology_weights[i].resize(num_switches);
-        topology_latency[i].resize(num_switches);
-        topology_bw_multis[i].resize(num_switches);
         m_component_latencies[i].resize(num_switches);
-
-        // FIXME setting the size of a member variable here is a HACK!
         m_component_inter_switches[i].resize(num_switches);
 
         for (int j = 0; j < topology_weights[i].size(); j++) {
             topology_weights[i][j] = INFINITE_LATENCY;
 
             // initialize to invalid values
-            topology_latency[i][j] = -1;
-            topology_bw_multis[i][j] = -1;
             m_component_latencies[i][j] = -1;
 
             // initially assume direct connections / no intermediate
@@ -175,89 +188,85 @@ Topology::createLinks(Network *net, bool isReconfiguration)
     }
 
     // Fill in the topology weights and bandwidth multipliers
-    for (int i = 0; i < m_links_src_vector.size(); i++) {
-        int src = m_links_src_vector[i];
-        int dst = m_links_dest_vector[i];
-        topology_weights[src][dst] = m_links_weight_vector[i];
-        topology_latency[src][dst] = m_links_latency_vector[i];
-        m_component_latencies[src][dst] = m_links_latency_vector[i];
-        topology_bw_multis[src][dst] = m_bw_multiplier_vector[i];
+    for (LinkMap::const_iterator i = m_link_map.begin();
+         i != m_link_map.end(); ++i) {
+        std::pair<int, int> src_dest = (*i).first;
+        BasicLink* link = (*i).second.link;
+        int src = src_dest.first;
+        int dst = src_dest.second;
+        m_component_latencies[src][dst] = link->m_latency;
+        topology_weights[src][dst] = link->m_weight;
     }
-
+        
     // Walk topology and hookup the links
     Matrix dist = shortest_path(topology_weights, m_component_latencies,
         m_component_inter_switches);
     for (int i = 0; i < topology_weights.size(); i++) {
         for (int j = 0; j < topology_weights[i].size(); j++) {
             int weight = topology_weights[i][j];
-            int bw_multiplier = topology_bw_multis[i][j];
-            int latency = topology_latency[i][j];
             if (weight > 0 && weight != INFINITE_LATENCY) {
                 NetDest destination_set = shortest_path_to_node(i, j,
-                    topology_weights, dist);
-                assert(latency != -1);
-                makeLink(net, i, j, destination_set, latency, weight,
-                    bw_multiplier, isReconfiguration);
+                                                     topology_weights, dist);
+                makeLink(net, i, j, destination_set, isReconfiguration);
             }
         }
     }
 }
 
-SwitchID
-Topology::newSwitchID()
-{
-    m_number_of_switches++;
-    return m_number_of_switches-1+m_nodes+m_nodes;
-}
-
 void
-Topology::addLink(SwitchID src, SwitchID dest, int link_latency)
-{
-    addLink(src, dest, link_latency, DEFAULT_BW_MULTIPLIER, link_latency);
-}
-
-void
-Topology::addLink(SwitchID src, SwitchID dest, int link_latency,
-    int bw_multiplier)
-{
-    addLink(src, dest, link_latency, bw_multiplier, link_latency);
-}
-
-void
-Topology::addLink(SwitchID src, SwitchID dest, int link_latency,
-    int bw_multiplier, int link_weight)
+Topology::addLink(SwitchID src, SwitchID dest, BasicLink* link, 
+                  LinkDirection dir)
 {
     assert(src <= m_number_of_switches+m_nodes+m_nodes);
     assert(dest <= m_number_of_switches+m_nodes+m_nodes);
-    m_links_src_vector.push_back(src);
-    m_links_dest_vector.push_back(dest);
-    m_links_latency_vector.push_back(link_latency);
-    m_links_weight_vector.push_back(link_weight);
-    m_bw_multiplier_vector.push_back(bw_multiplier);
+    
+    std::pair<int, int> src_dest_pair;
+    LinkEntry link_entry;
+
+    src_dest_pair.first = src;
+    src_dest_pair.second = dest;
+    link_entry.direction = dir;
+    link_entry.link = link;
+    m_link_map[src_dest_pair] = link_entry;
 }
 
 void
 Topology::makeLink(Network *net, SwitchID src, SwitchID dest,
-    const NetDest& routing_table_entry, int link_latency, int link_weight,
-    int bw_multiplier, bool isReconfiguration)
+                   const NetDest& routing_table_entry, bool isReconfiguration)
 {
     // Make sure we're not trying to connect two end-point nodes
     // directly together
     assert(src >= 2 * m_nodes || dest >= 2 * m_nodes);
 
+    std::pair<int, int> src_dest;
+    LinkEntry link_entry;    
+
     if (src < m_nodes) {
-        net->makeInLink(src, dest-(2*m_nodes), routing_table_entry,
-            link_latency, bw_multiplier, isReconfiguration);
+        src_dest.first = src;
+        src_dest.second = dest;
+        link_entry = m_link_map[src_dest];
+        net->makeInLink(src, dest - (2 * m_nodes), link_entry.link,
+                        link_entry.direction, 
+                        routing_table_entry,
+                        isReconfiguration);
     } else if (dest < 2*m_nodes) {
         assert(dest >= m_nodes);
-        NodeID node = dest-m_nodes;
-        net->makeOutLink(src-(2*m_nodes), node, routing_table_entry,
-            link_latency, link_weight, bw_multiplier, isReconfiguration);
+        NodeID node = dest - m_nodes;
+        src_dest.first = src;
+        src_dest.second = dest;
+        link_entry = m_link_map[src_dest];
+        net->makeOutLink(src - (2 * m_nodes), node, link_entry.link,
+                         link_entry.direction, 
+                         routing_table_entry,
+                         isReconfiguration);
     } else {
-        assert((src >= 2*m_nodes) && (dest >= 2*m_nodes));
-        net->makeInternalLink(src-(2*m_nodes), dest-(2*m_nodes),
-            routing_table_entry, link_latency, link_weight, bw_multiplier,
-            isReconfiguration);
+        assert((src >= 2 * m_nodes) && (dest >= 2 * m_nodes));
+        src_dest.first = src;
+        src_dest.second = dest;
+        link_entry = m_link_map[src_dest];
+        net->makeInternalLink(src - (2 * m_nodes), dest - (2 * m_nodes),
+                              link_entry.link, link_entry.direction,
+                              routing_table_entry, isReconfiguration);
     }
 }
 
@@ -423,20 +432,3 @@ TopologyParams::create()
     return new Topology(this);
 }
 
-Link *
-LinkParams::create()
-{
-    return new Link(this);
-}
-
-ExtLink *
-ExtLinkParams::create()
-{
-    return new ExtLink(this);
-}
-
-IntLink *
-IntLinkParams::create()
-{
-    return new IntLink(this);
-}
index c92848d8ff71015b1491e70167fc73e0647a49a7..7b74396869881bb28a6be4adddfa537c14777ec5 100644 (file)
 #include <string>
 #include <vector>
 
+#include "mem/protocol/LinkDirection.hh"
 #include "mem/ruby/common/Global.hh"
 #include "mem/ruby/system/NodeID.hh"
-#include "params/ExtLink.hh"
-#include "params/IntLink.hh"
-#include "params/Link.hh"
 #include "params/Topology.hh"
 #include "sim/sim_object.hh"
 
-class Network;
 class NetDest;
+class Network;
 
 typedef std::vector<std::vector<int> > Matrix;
 
-class Link : public SimObject
-{
-  public:
-    typedef LinkParams Params;
-    Link(const Params *p) : SimObject(p) {}
-    const Params *params() const { return (const Params *)_params; }
-};
-
-class ExtLink : public Link
+struct LinkEntry 
 {
-  public:
-    typedef ExtLinkParams Params;
-    ExtLink(const Params *p) : Link(p) {}
-    const Params *params() const { return (const Params *)_params; }
+    BasicLink *link;
+    LinkDirection direction;
 };
 
-class IntLink : public Link
-{
-  public:
-    typedef IntLinkParams Params;
-    IntLink(const Params *p) : Link(p) {}
-    const Params *params() const { return (const Params *)_params; }
-};
+typedef std::map<std::pair<int, int>, LinkEntry> LinkMap;
 
 class Topology : public SimObject
 {
@@ -89,6 +71,7 @@ class Topology : public SimObject
     virtual ~Topology() {}
     const Params *params() const { return (const Params *)_params; }
 
+    void init();
     int numSwitches() const { return m_number_of_switches; }
     void createLinks(Network *net, bool isReconfiguration);
 
@@ -101,19 +84,11 @@ class Topology : public SimObject
     void print(std::ostream& out) const { out << "[Topology]"; }
 
   protected:
-    SwitchID newSwitchID();
-    void addLink(SwitchID src, SwitchID dest, int link_latency);
-    void addLink(SwitchID src, SwitchID dest, int link_latency,
-        int bw_multiplier);
-    void addLink(SwitchID src, SwitchID dest, int link_latency,
-        int bw_multiplier, int link_weight);
+    void addLink(SwitchID src, SwitchID dest, BasicLink* link,
+                 LinkDirection dir);
     void makeLink(Network *net, SwitchID src, SwitchID dest,
-        const NetDest& routing_table_entry, int link_latency, int weight,
-        int bw_multiplier, bool isReconfiguration);
-
-    //void makeSwitchesPerChip(std::vector<std::vector<SwitchID > > &nodePairs,
-    //    std::vector<int> &latencies, std::vector<int> &bw_multis,
-    //    int numberOfChips);
+                  const NetDest& routing_table_entry, 
+                  bool isReconfiguration);
 
     std::string getDesignStr();
     // Private copy constructor and assignment operator
@@ -126,15 +101,14 @@ class Topology : public SimObject
     int m_number_of_switches;
 
     std::vector<AbstractController*> m_controller_vector;
-
-    std::vector<SwitchID> m_links_src_vector;
-    std::vector<SwitchID> m_links_dest_vector;
-    std::vector<int> m_links_latency_vector;
-    std::vector<int> m_links_weight_vector;
-    std::vector<int> m_bw_multiplier_vector;
+    std::vector<BasicExtLink*> m_ext_link_vector;
+    std::vector<BasicIntLink*> m_int_link_vector;
 
     Matrix m_component_latencies;
     Matrix m_component_inter_switches;
+
+    LinkMap m_link_map;
+    std::vector<BasicRouter*> m_router_vector;
 };
 
 inline std::ostream&
index 77916133621c1f01499a20310f275bad33143c52..e6c39475d6450901d3a6c863292262e2a23d596f 100644 (file)
 #define __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_CREDIT_LINK_D_HH__
 
 #include "mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh"
+#include "params/CreditLink_d.hh"
 
 class CreditLink_d : public NetworkLink_d
 {
   public:
-    CreditLink_d(int id, int link_latency, GarnetNetwork_d *net_ptr)
-        : NetworkLink_d(id, link_latency, net_ptr)
-    {}
+    typedef CreditLink_dParams Params;
+    CreditLink_d(const Params *p) : NetworkLink_d(p) {}
 };
 
 #endif // __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_CREDIT_LINK_D_HH__
diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.cc
new file mode 100644 (file)
index 0000000..da92496
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2011 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 "mem/ruby/network/garnet/fixed-pipeline/CreditLink_d.hh"
+#include "mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.hh"
+#include "mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh"
+
+GarnetIntLink_d::GarnetIntLink_d(const Params *p)
+    : BasicLink(p)
+{
+    m_network_links[0] = p->network_links[0];
+    m_credit_links[0] = p->credit_links[0];
+    m_network_links[1] = p->network_links[1];
+    m_credit_links[1] = p->credit_links[1];
+}
+
+void
+GarnetIntLink_d::init()
+{
+}
+
+void
+GarnetIntLink_d::print(std::ostream& out) const
+{
+    out << name();
+}
+
+GarnetIntLink_d *
+GarnetIntLink_dParams::create()
+{
+    return new GarnetIntLink_d(this);
+}
+
+GarnetExtLink_d::GarnetExtLink_d(const Params *p)
+    : BasicLink(p)
+{
+    m_network_links[0] = p->network_links[0];
+    m_credit_links[0] = p->credit_links[0];
+    m_network_links[1] = p->network_links[1];
+    m_credit_links[1] = p->credit_links[1];
+}
+
+void
+GarnetExtLink_d::init()
+{
+}
+
+void
+GarnetExtLink_d::print(std::ostream& out) const
+{
+    out << name();
+}
+
+GarnetExtLink_d *
+GarnetExtLink_dParams::create()
+{
+    return new GarnetExtLink_d(this);
+}
diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.hh b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.hh
new file mode 100644 (file)
index 0000000..cb2ae62
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2011 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_NETWORK_GARNET_FIXED_PIPELINE_LINK_HH__
+#define __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_LINK_HH__
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include "mem/ruby/network/BasicLink.hh"
+#include "mem/ruby/network/garnet/fixed-pipeline/CreditLink_d.hh"
+#include "mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh"
+#include "params/GarnetIntLink_d.hh"
+#include "params/GarnetExtLink_d.hh"
+
+class GarnetIntLink_d : public BasicLink
+{
+  public:
+    typedef GarnetIntLink_dParams Params;
+    GarnetIntLink_d(const Params *p);
+
+    void init();
+
+    void print(std::ostream& out) const;
+
+    friend class GarnetNetwork_d;
+
+  protected:
+    NetworkLink_d* m_network_links[2];
+    CreditLink_d* m_credit_links[2];
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, const GarnetIntLink_d& obj)
+{
+    obj.print(out);
+    out << std::flush;
+    return out;
+}
+
+class GarnetExtLink_d : public BasicLink
+{
+  public:
+    typedef GarnetExtLink_dParams Params;
+    GarnetExtLink_d(const Params *p);
+
+    void init();
+
+    void print(std::ostream& out) const;
+
+    friend class GarnetNetwork_d;
+
+  protected:
+    NetworkLink_d* m_network_links[2];
+    CreditLink_d* m_credit_links[2];
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, const GarnetExtLink_d& obj)
+{
+    obj.print(out);
+    out << std::flush;
+    return out;
+}
+
+#endif // __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_LINK_HH__
diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.py b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.py
new file mode 100644 (file)
index 0000000..941746c
--- /dev/null
@@ -0,0 +1,85 @@
+# Copyright (c) 2008 Princeton University
+# 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 m5.proxy import *
+from m5.SimObject import SimObject
+from BasicLink import BasicIntLink, BasicExtLink
+
+class NetworkLink_d(SimObject):
+    type = 'NetworkLink_d'
+    link_id = Param.Int(Parent.link_id, "link id")
+    link_latency = Param.Int(Parent.latency, "link latency")
+    vcs_per_class = Param.Int(Parent.vcs_per_class,
+                              "virtual channels per message class")
+    virt_nets = Param.Int(Parent.number_of_virtual_networks,
+                          "number of virtual networks")
+    channel_width = Param.Int(Parent.flit_size, "channel width == flit size")
+
+class CreditLink_d(NetworkLink_d):
+    type = 'CreditLink_d'
+
+# Interior fixed pipeline links between routers
+class GarnetIntLink_d(BasicIntLink):
+    type = 'GarnetIntLink_d'
+    # The detailed fixed pipeline bi-directional link include two main
+    # forward links and two backward flow-control links, one per direction
+    nls = []
+    # In uni-directional link
+    nls.append(NetworkLink_d()); 
+    # Out uni-directional link
+    nls.append(NetworkLink_d());
+    network_links = VectorParam.NetworkLink_d(nls, "forward links")
+
+    cls = []
+    # In uni-directional link
+    cls.append(CreditLink_d());
+    # Out uni-directional link
+    cls.append(CreditLink_d());
+    credit_links = VectorParam.CreditLink_d(cls, "backward flow-control links")
+
+# Exterior fixed pipeline links between a router and a controller
+class GarnetExtLink_d(BasicExtLink):
+    type = 'GarnetExtLink_d'
+    # The detailed fixed pipeline bi-directional link include two main
+    # forward links and two backward flow-control links, one per direction
+    nls = []
+    # In uni-directional link
+    nls.append(NetworkLink_d());
+    # Out uni-directional link
+    nls.append(NetworkLink_d());
+    network_links = VectorParam.NetworkLink_d(nls, "forward links")
+
+    cls = []
+    # In uni-directional link
+    cls.append(CreditLink_d());
+    # Out uni-directional link
+    cls.append(CreditLink_d());
+    credit_links = VectorParam.CreditLink_d(cls, "backward flow-control links")
index 265023b7e5d1546733c55c43f666cb55ee23997d..5aa9ceca863b8268d53b8fbcedaaaa2d372563d3 100644 (file)
@@ -34,7 +34,9 @@
 #include "mem/protocol/MachineType.hh"
 #include "mem/ruby/buffers/MessageBuffer.hh"
 #include "mem/ruby/common/NetDest.hh"
+#include "mem/ruby/network/garnet/BaseGarnetNetwork.hh"
 #include "mem/ruby/network/garnet/fixed-pipeline/CreditLink_d.hh"
+#include "mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.hh"
 #include "mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh"
 #include "mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.hh"
 #include "mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh"
@@ -53,7 +55,13 @@ GarnetNetwork_d::GarnetNetwork_d(const Params *p)
     m_network_latency = 0.0;
     m_queueing_latency = 0.0;
 
-    m_router_ptr_vector.clear();
+    // record the routers
+    for (vector<BasicRouter*>::const_iterator i = 
+             m_topology_ptr->params()->routers.begin();
+         i != m_topology_ptr->params()->routers.end(); ++i) {
+        Router_d* router = safe_cast<Router_d*>(*i);
+        m_router_ptr_vector.push_back(router);
+    }
 
     // Queues that are getting messages from protocol
     m_toNetQueues.resize(m_nodes);
@@ -87,15 +95,17 @@ GarnetNetwork_d::init()
 {
     BaseGarnetNetwork::init();
 
+    // initialize the router's network pointers
+    for (vector<Router_d*>::const_iterator i = m_router_ptr_vector.begin();
+         i != m_router_ptr_vector.end(); ++i) {
+        Router_d* router = safe_cast<Router_d*>(*i);
+        router->init_net_ptr(this);
+    }
+
     // The topology pointer should have already been initialized in the
     // parent network constructor
     assert(m_topology_ptr != NULL);
 
-    int number_of_routers = m_topology_ptr->numSwitches();
-    for (int i=0; i<number_of_routers; i++) {
-        m_router_ptr_vector.push_back(new Router_d(i, this));
-    }
-
     for (int i=0; i < m_nodes; i++) {
         NetworkInterface_d *ni = new NetworkInterface_d(i, m_virtual_networks,
                                                         this);
@@ -104,9 +114,6 @@ GarnetNetwork_d::init()
     }
     // false because this isn't a reconfiguration
     m_topology_ptr->createLinks(this, false);
-    for (int i = 0; i < m_router_ptr_vector.size(); i++) {
-        m_router_ptr_vector[i]->init();
-    }
 
     m_vnet_type.resize(m_virtual_networks);
     for (int i = 0; i < m_vnet_type.size(); i++) {
@@ -147,17 +154,19 @@ GarnetNetwork_d::reset()
 */
 
 void
-GarnetNetwork_d::makeInLink(NodeID src, SwitchID dest,
-    const NetDest& routing_table_entry, int link_latency, int bw_multiplier,
-    bool isReconfiguration)
+GarnetNetwork_d::makeInLink(NodeID src, SwitchID dest, BasicLink* link,
+                            LinkDirection direction,
+                            const NetDest& routing_table_entry,
+                            bool isReconfiguration)
 {
     assert(src < m_nodes);
 
+    GarnetExtLink_d* garnet_link = safe_cast<GarnetExtLink_d*>(link);
+
     if (!isReconfiguration) {
-        NetworkLink_d *net_link = new NetworkLink_d
-            (m_link_ptr_vector.size(), link_latency, this);
-        CreditLink_d *credit_link = new CreditLink_d
-            (m_creditlink_ptr_vector.size(), link_latency, this);
+        NetworkLink_d* net_link = garnet_link->m_network_links[direction];
+        CreditLink_d* credit_link = garnet_link->m_credit_links[direction];
+
         m_link_ptr_vector.push_back(net_link);
         m_creditlink_ptr_vector.push_back(credit_link);
 
@@ -176,24 +185,27 @@ GarnetNetwork_d::makeInLink(NodeID src, SwitchID dest,
 */
 
 void
-GarnetNetwork_d::makeOutLink(SwitchID src, NodeID dest,
-    const NetDest& routing_table_entry, int link_latency, int link_weight,
-    int bw_multiplier, bool isReconfiguration)
+GarnetNetwork_d::makeOutLink(SwitchID src, NodeID dest, BasicLink* link,
+                             LinkDirection direction,
+                             const NetDest& routing_table_entry,
+                             bool isReconfiguration)
 {
     assert(dest < m_nodes);
     assert(src < m_router_ptr_vector.size());
     assert(m_router_ptr_vector[src] != NULL);
 
+    GarnetExtLink_d* garnet_link = safe_cast<GarnetExtLink_d*>(link);
+
     if (!isReconfiguration) {
-        NetworkLink_d *net_link = new NetworkLink_d
-            (m_link_ptr_vector.size(), link_latency, this);
-        CreditLink_d *credit_link = new CreditLink_d
-            (m_creditlink_ptr_vector.size(), link_latency, this);
+        NetworkLink_d* net_link = garnet_link->m_network_links[direction];
+        CreditLink_d* credit_link = garnet_link->m_credit_links[direction];
+
         m_link_ptr_vector.push_back(net_link);
         m_creditlink_ptr_vector.push_back(credit_link);
 
         m_router_ptr_vector[src]->addOutPort(net_link, routing_table_entry,
-                                             link_weight, credit_link);
+                                             link->m_weight, 
+                                             credit_link);
         m_ni_ptr_vector[dest]->addInPort(net_link, credit_link);
     } else {
         fatal("Fatal Error:: Reconfiguration not allowed here");
@@ -206,21 +218,24 @@ GarnetNetwork_d::makeOutLink(SwitchID src, NodeID dest,
 */
 
 void
-GarnetNetwork_d::makeInternalLink(SwitchID src, SwitchID dest,
-    const NetDest& routing_table_entry, int link_latency, int link_weight,
-    int bw_multiplier, bool isReconfiguration)
+GarnetNetwork_d::makeInternalLink(SwitchID src, SwitchID dest, BasicLink* link,
+                                  LinkDirection direction,
+                                  const NetDest& routing_table_entry,
+                                  bool isReconfiguration)
 {
+    GarnetIntLink_d* garnet_link = safe_cast<GarnetIntLink_d*>(link);
+
     if (!isReconfiguration) {
-        NetworkLink_d *net_link = new NetworkLink_d
-            (m_link_ptr_vector.size(), link_latency, this);
-        CreditLink_d *credit_link = new CreditLink_d
-            (m_creditlink_ptr_vector.size(), link_latency, this);
+        NetworkLink_d* net_link = garnet_link->m_network_links[direction];
+        CreditLink_d* credit_link = garnet_link->m_credit_links[direction];
+
         m_link_ptr_vector.push_back(net_link);
         m_creditlink_ptr_vector.push_back(credit_link);
 
         m_router_ptr_vector[dest]->addInPort(net_link, credit_link);
         m_router_ptr_vector[src]->addOutPort(net_link, routing_table_entry,
-                                             link_weight, credit_link);
+                                             link->m_weight, 
+                                             credit_link);
     } else {
         fatal("Fatal Error:: Reconfiguration not allowed here");
         // do nothing
index f403660ea225fec67b02b097372738255ec60dff..7c6e5f8e1caac7e1b78053cf59e83d3ce000b2b2 100644 (file)
@@ -105,15 +105,18 @@ class GarnetNetwork_d : public BaseGarnetNetwork
     void reset();
 
     // Methods used by Topology to setup the network
-    void makeOutLink(SwitchID src, NodeID dest,
-        const NetDest& routing_table_entry, int link_latency, int link_weight,
-        int bw_multiplier, bool isReconfiguration);
-    void makeInLink(SwitchID src, NodeID dest,
-        const NetDest& routing_table_entry, int link_latency,
-        int bw_multiplier, bool isReconfiguration);
-    void makeInternalLink(SwitchID src, NodeID dest,
-        const NetDest& routing_table_entry, int link_latency, int link_weight,
-        int bw_multiplier, bool isReconfiguration);
+    void makeOutLink(SwitchID src, NodeID dest, BasicLink* link, 
+                     LinkDirection direction,
+                     const NetDest& routing_table_entry,
+                     bool isReconfiguration);
+    void makeInLink(NodeID src, SwitchID dest, BasicLink* link,
+                    LinkDirection direction,
+                    const NetDest& routing_table_entry,
+                    bool isReconfiguration);
+    void makeInternalLink(SwitchID src, SwitchID dest, BasicLink* link,
+                          LinkDirection direction,
+                          const NetDest& routing_table_entry,
+                          bool isReconfiguration);
 
   private:
     void checkNetworkAllocation(NodeID id, bool ordered, int network_num);
diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetRouter_d.py b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetRouter_d.py
new file mode 100644 (file)
index 0000000..92e49b3
--- /dev/null
@@ -0,0 +1,44 @@
+# Copyright (c) 2008 Princeton University
+# 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 m5.proxy import *
+from BasicRouter import BasicRouter
+
+class GarnetRouter_d(BasicRouter):
+    type = 'GarnetRouter_d'
+    cxx_class = 'Router_d'
+    vcs_per_class = Param.Int(Parent.vcs_per_class,
+                              "virtual channels per message class")
+    virt_nets = Param.Int(Parent.number_of_virtual_networks,
+                          "number of virtual networks")
+    flit_width = Param.Int(Parent.flit_size, "flit width == flit size")
+
+
index 72439a67bbbb6ba5b71f45fe61f7fe710705ffd2..38627b109e904d290ec514e5e228bb257e576e53 100644 (file)
  * Authors: Niket Agarwal
  */
 
-#include "mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh"
+#include "mem/ruby/network/garnet/fixed-pipeline/CreditLink_d.hh"
 #include "mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh"
 
-NetworkLink_d::NetworkLink_d(int id, int link_latency, GarnetNetwork_d *net_ptr)
+NetworkLink_d::NetworkLink_d(const Params *p)
+    : SimObject(p)
 {
-    m_net_ptr = net_ptr;
-    m_id = id;
-    m_latency = link_latency;
+    m_latency = p->link_latency;
+    channel_width = p->channel_width;
+    m_id = p->link_id;
     linkBuffer = new flitBuffer_d();
     m_link_utilized = 0;
-    m_vc_load.resize(m_net_ptr->getVCsPerClass() *
-                     net_ptr->getNumberOfVirtualNetworks());
+    m_vc_load.resize(p->vcs_per_class * p->virt_nets);
 
-    for (int i = 0;
-        i < m_net_ptr->getVCsPerClass()*net_ptr->getNumberOfVirtualNetworks();
-        i++) {
+    for (int i = 0; i < (p->vcs_per_class * p->virt_nets); i++) {
         m_vc_load[i] = 0;
     }
 }
@@ -89,3 +87,15 @@ NetworkLink_d::getLinkUtilization()
 {
     return m_link_utilized;
 }
+
+NetworkLink_d *
+NetworkLink_dParams::create()
+{
+    return new NetworkLink_d(this);
+}
+
+CreditLink_d *
+CreditLink_dParams::create()
+{
+    return new CreditLink_d(this);
+}
index a46c59f41963f28c70e179f58747647bb7252563..5da006c4d50378374475ab8168d6753a25003243 100644 (file)
 #include "mem/ruby/network/garnet/fixed-pipeline/flitBuffer_d.hh"
 #include "mem/ruby/network/garnet/NetworkHeader.hh"
 #include "mem/ruby/network/orion/NetworkPower.hh"
+#include "params/NetworkLink_d.hh"
+#include "sim/sim_object.hh"
 
 class GarnetNetwork_d;
 
-class NetworkLink_d : public Consumer
+class NetworkLink_d : public SimObject, public Consumer
 {
   public:
-    //NetworkLink_d(int id);
+    typedef NetworkLink_dParams Params;
+    NetworkLink_d(const Params *p);
     ~NetworkLink_d();
 
-    NetworkLink_d(int id, int link_latency, GarnetNetwork_d *net_ptr);
     void setLinkConsumer(Consumer *consumer);
     void setSourceQueue(flitBuffer_d *srcQueue);
     void print(std::ostream& out) const{}
@@ -67,8 +69,8 @@ class NetworkLink_d : public Consumer
   protected:
     int m_id;
     int m_latency;
-    GarnetNetwork_d *m_net_ptr;
 
+    int channel_width;
     flitBuffer_d *linkBuffer;
     Consumer *link_consumer;
     flitBuffer_d *link_srcQueue;
index 15cddd3b7bd278455433332e1867eb9de229a496..5eefd52debd0b2a43cfffef9af2c7971a43e2bbd 100644 (file)
 using namespace std;
 using m5::stl_helpers::deletePointers;
 
-Router_d::Router_d(int id, GarnetNetwork_d *network_ptr)
+Router_d::Router_d(const Params *p)
+    : BasicRouter(p)
 {
-    m_id = id;
-    m_network_ptr = network_ptr;
-    m_virtual_networks = network_ptr->getNumberOfVirtualNetworks();
-    m_vc_per_vnet = m_network_ptr->getVCsPerClass();
-    m_num_vcs = m_virtual_networks*m_vc_per_vnet;
-    m_flit_width = m_network_ptr->getFlitSize();
+    m_virtual_networks = p->virt_nets;
+    m_vc_per_vnet = p->vcs_per_class;
+    m_num_vcs = m_virtual_networks * m_vc_per_vnet;
+    m_flit_width = p->flit_width;
 
     m_routing_unit = new RoutingUnit_d(this);
     m_vc_alloc = new VCallocator_d(this);
@@ -88,6 +87,8 @@ Router_d::~Router_d()
 void
 Router_d::init()
 {
+    BasicRouter::init();
+
     m_vc_alloc->init();
     m_sw_alloc->init();
     m_switch->init();
@@ -178,7 +179,7 @@ Router_d::calculate_performance_numbers()
 void
 Router_d::printConfig(ostream& out)
 {
-    out << "[Router " << m_id << "] :: " << endl;
+    out << name() << endl;
     out << "[inLink - ";
     for (int i = 0;i < m_input_unit.size(); i++)
         out << m_input_unit[i]->get_inlink_id() << " - ";
@@ -188,3 +189,9 @@ Router_d::printConfig(ostream& out)
         out << m_output_unit[i]->get_outlink_id() << " - ";
     out << "]" << endl;
 }
+
+Router_d *
+GarnetRouter_dParams::create()
+{
+    return new Router_d(this);
+}
index 4c2b83312e63202682c8c04aece1e75e717ec390..ec44cc7b310242927d249f1fabc1a824942457d3 100644 (file)
 #include <vector>
 
 #include "mem/ruby/common/NetDest.hh"
+#include "mem/ruby/network/BasicRouter.hh"
 #include "mem/ruby/network/garnet/fixed-pipeline/flit_d.hh"
 #include "mem/ruby/network/garnet/NetworkHeader.hh"
 #include "mem/ruby/network/orion/NetworkPower.hh"
+#include "params/GarnetRouter_d.hh"
 
 class GarnetNetwork_d;
 class NetworkLink_d;
@@ -49,10 +51,11 @@ class VCallocator_d;
 class SWallocator_d;
 class Switch_d;
 
-class Router_d
+class Router_d : public BasicRouter
 {
   public:
-    Router_d(int id, GarnetNetwork_d *network_ptr);
+    typedef GarnetRouter_dParams Params;
+    Router_d(const Params *p);
 
     ~Router_d();
 
@@ -68,6 +71,11 @@ class Router_d
     int get_num_outports()  { return m_output_unit.size(); }
     int get_id()            { return m_id; }
 
+    void init_net_ptr(GarnetNetwork_d* net_ptr) 
+    { 
+        m_network_ptr = net_ptr; 
+    }
+
     GarnetNetwork_d* get_net_ptr()                  { return m_network_ptr; }
     std::vector<InputUnit_d *>& get_inputUnit_ref()   { return m_input_unit; }
     std::vector<OutputUnit_d *>& get_outputUnit_ref() { return m_output_unit; }
@@ -86,7 +94,6 @@ class Router_d
     double get_static_power(){return m_power_sta;}
 
   private:
-    int m_id;
     int m_virtual_networks, m_num_vcs, m_vc_per_vnet;
     GarnetNetwork_d *m_network_ptr;
     int m_flit_width;
index d3cf4587851f392692df50e826a8118086c133e3..ae3b964de52cf9f9a45985c5603a0debf5dc4f10 100644 (file)
@@ -33,8 +33,11 @@ Import('*')
 if not env['RUBY']:
     Return()
 
+SimObject('GarnetLink_d.py')
 SimObject('GarnetNetwork_d.py')
+SimObject('GarnetRouter_d.py')
 
+Source('GarnetLink_d.cc')
 Source('GarnetNetwork_d.cc', Werror=False)
 Source('InputUnit_d.cc', Werror=False)
 Source('NetworkInterface_d.cc')
diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.cc b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.cc
new file mode 100644 (file)
index 0000000..270b132
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2011 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 "mem/ruby/network/garnet/flexible-pipeline/GarnetLink.hh"
+#include "mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh"
+
+GarnetIntLink::GarnetIntLink(const Params *p)
+    : BasicLink(p)
+{
+    m_network_links[0] = p->network_links[0];
+    m_network_links[1] = p->network_links[1];
+}
+
+void
+GarnetIntLink::init()
+{
+}
+
+void
+GarnetIntLink::print(std::ostream& out) const
+{
+    out << name();
+}
+
+GarnetIntLink *
+GarnetIntLinkParams::create()
+{
+    return new GarnetIntLink(this);
+}
+
+GarnetExtLink::GarnetExtLink(const Params *p)
+    : BasicLink(p)
+{
+    m_network_links[0] = p->network_links[0];
+    m_network_links[1] = p->network_links[1];
+}
+
+void
+GarnetExtLink::init()
+{
+}
+
+void
+GarnetExtLink::print(std::ostream& out) const
+{
+    out << name();
+}
+
+GarnetExtLink *
+GarnetExtLinkParams::create()
+{
+    return new GarnetExtLink(this);
+}
diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.hh b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.hh
new file mode 100644 (file)
index 0000000..cd42378
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2011 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_NETWORK_GARNET_FLEXIBLE_PIPELINE_LINK_HH__
+#define __MEM_RUBY_NETWORK_GARNET_FLEXIBLE_PIPELINE_LINK_HH__
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include "mem/ruby/network/BasicLink.hh"
+#include "mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh"
+#include "params/GarnetIntLink.hh"
+#include "params/GarnetExtLink.hh"
+
+class GarnetIntLink : public BasicLink
+{
+  public:
+    typedef GarnetIntLinkParams Params;
+    GarnetIntLink(const Params *p);
+
+    void init();
+
+    void print(std::ostream& out) const;
+
+    friend class GarnetNetwork;
+
+  protected:
+    NetworkLink* m_network_links[2];
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, const GarnetIntLink& obj)
+{
+    obj.print(out);
+    out << std::flush;
+    return out;
+}
+
+class GarnetExtLink : public BasicLink
+{
+  public:
+    typedef GarnetExtLinkParams Params;
+    GarnetExtLink(const Params *p);
+
+    void init();
+
+    void print(std::ostream& out) const;
+
+    friend class GarnetNetwork;
+
+  protected:
+    NetworkLink* m_network_links[2];
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, const GarnetExtLink& obj)
+{
+    obj.print(out);
+    out << std::flush;
+    return out;
+}
+
+#endif // __MEM_RUBY_NETWORK_GARNET_FLEXIBLE_PIPELINE_LINK_HH__
diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.py b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.py
new file mode 100644 (file)
index 0000000..45c56fa
--- /dev/null
@@ -0,0 +1,68 @@
+# Copyright (c) 2008 Princeton University
+# 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 m5.proxy import *
+from m5.SimObject import SimObject
+from BasicLink import BasicIntLink, BasicExtLink
+
+class NetworkLink(SimObject):
+    type = 'NetworkLink'
+    link_id = Param.Int(Parent.link_id, "link id")
+    link_latency = Param.Int(Parent.latency, "link latency")
+    vcs_per_class = Param.Int(Parent.vcs_per_class,
+                              "virtual channels per message class")
+    virt_nets = Param.Int(Parent.number_of_virtual_networks,
+                          "number of virtual networks")
+    channel_width = Param.Int(Parent.flit_size, "channel width == flit size")
+
+# Interior fixed pipeline links between routers
+class GarnetIntLink(BasicIntLink):
+    type = 'GarnetIntLink'
+    # The flexible pipeline bi-directional link only include two main
+    # forward links and no backward flow-control links
+    nls = []
+    # In uni-directional link
+    nls.append(NetworkLink()); 
+    # Out uni-directional link
+    nls.append(NetworkLink());
+    network_links = VectorParam.NetworkLink(nls, "forward links")
+
+# Exterior fixed pipeline links between a router and a controller
+class GarnetExtLink(BasicExtLink):
+    type = 'GarnetExtLink'
+    # The flexible pipeline bi-directional link only include two main
+    # forward links and no backward flow-control links
+    nls = []
+    # In uni-directional link
+    nls.append(NetworkLink());
+    # Out uni-directional link
+    nls.append(NetworkLink());
+    network_links = VectorParam.NetworkLink(nls, "forward links")
index 8e919284aacaa4b11be65fdf0526395d88bac071..16c56e95e76430e6d4b8d7f4f711fbd982b073c1 100644 (file)
@@ -34,6 +34,8 @@
 #include "mem/protocol/MachineType.hh"
 #include "mem/ruby/buffers/MessageBuffer.hh"
 #include "mem/ruby/common/NetDest.hh"
+#include "mem/ruby/network/BasicLink.hh"
+#include "mem/ruby/network/garnet/flexible-pipeline/GarnetLink.hh"
 #include "mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.hh"
 #include "mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.hh"
 #include "mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh"
@@ -52,6 +54,14 @@ GarnetNetwork::GarnetNetwork(const Params *p)
     m_network_latency = 0.0;
     m_queueing_latency = 0.0;
 
+    // record the routers
+    for (vector<BasicRouter*>::const_iterator i = 
+             m_topology_ptr->params()->routers.begin();
+         i != m_topology_ptr->params()->routers.end(); ++i) {
+        Router* router = safe_cast<Router*>(*i);
+        m_router_ptr_vector.push_back(router);
+    }
+
     // Allocate to and from queues
 
     // Queues that are getting messages from protocol
@@ -89,9 +99,11 @@ GarnetNetwork::init()
     // Setup the network switches
     assert (m_topology_ptr!=NULL);
 
-    int number_of_routers = m_topology_ptr->numSwitches();
-    for (int i=0; i<number_of_routers; i++) {
-        m_router_ptr_vector.push_back(new Router(i, this));
+    // initialize the router's network pointers
+    for (vector<Router*>::const_iterator i = m_router_ptr_vector.begin();
+         i != m_router_ptr_vector.end(); ++i) {
+        Router* router = safe_cast<Router*>(*i);
+        router->init_net_ptr(this);
     }
 
     for (int i=0; i < m_nodes; i++) {
@@ -129,15 +141,18 @@ GarnetNetwork::reset()
 }
 
 void
-GarnetNetwork::makeInLink(NodeID src, SwitchID dest,
-    const NetDest& routing_table_entry, int link_latency, int bw_multiplier,
-    bool isReconfiguration)
+GarnetNetwork::makeInLink(NodeID src, SwitchID dest, BasicLink* link, 
+                          LinkDirection direction, 
+                          const NetDest& routing_table_entry, 
+                          bool isReconfiguration)
 {
     assert(src < m_nodes);
 
+    GarnetExtLink* garnet_link = safe_cast<GarnetExtLink*>(link);
+
     if (!isReconfiguration) {
-        NetworkLink *net_link = new NetworkLink(m_link_ptr_vector.size(),
-                                                link_latency, this);
+        NetworkLink *net_link = garnet_link->m_network_links[direction];
+        net_link->init_net_ptr(this);
         m_link_ptr_vector.push_back(net_link);
         m_router_ptr_vector[dest]->addInPort(net_link);
         m_ni_ptr_vector[src]->addOutPort(net_link);
@@ -148,20 +163,23 @@ GarnetNetwork::makeInLink(NodeID src, SwitchID dest,
 }
 
 void
-GarnetNetwork::makeOutLink(SwitchID src, NodeID dest,
-    const NetDest& routing_table_entry, int link_latency, int link_weight,
-    int bw_multiplier, bool isReconfiguration)
+GarnetNetwork::makeOutLink(SwitchID src, NodeID dest, BasicLink* link, 
+                           LinkDirection direction, 
+                           const NetDest& routing_table_entry, 
+                           bool isReconfiguration)
 {
     assert(dest < m_nodes);
     assert(src < m_router_ptr_vector.size());
     assert(m_router_ptr_vector[src] != NULL);
 
+    GarnetExtLink* garnet_link = safe_cast<GarnetExtLink*>(link);
+
     if (!isReconfiguration) {
-        NetworkLink *net_link = new NetworkLink(m_link_ptr_vector.size(),
-                                                link_latency, this);
+        NetworkLink *net_link = garnet_link->m_network_links[direction];
+        net_link->init_net_ptr(this);
         m_link_ptr_vector.push_back(net_link);
         m_router_ptr_vector[src]->addOutPort(net_link, routing_table_entry,
-                                             link_weight);
+                                             link->m_weight);
         m_ni_ptr_vector[dest]->addInPort(net_link);
     }         else {
         fatal("Fatal Error:: Reconfiguration not allowed here");
@@ -170,17 +188,20 @@ GarnetNetwork::makeOutLink(SwitchID src, NodeID dest,
 }
 
 void
-GarnetNetwork::makeInternalLink(SwitchID src, SwitchID dest,
-    const NetDest& routing_table_entry, int link_latency, int link_weight,
-    int bw_multiplier, bool isReconfiguration)
+GarnetNetwork::makeInternalLink(SwitchID src, SwitchID dest, BasicLink* link,
+                                LinkDirection direction, 
+                                const NetDest& routing_table_entry, 
+                                bool isReconfiguration)
 {
+    GarnetIntLink* garnet_link = safe_cast<GarnetIntLink*>(link);
+
     if (!isReconfiguration) {
-        NetworkLink *net_link = new NetworkLink(m_link_ptr_vector.size(),
-                                                link_latency, this);
+        NetworkLink *net_link = garnet_link->m_network_links[direction];
+        net_link->init_net_ptr(this);
         m_link_ptr_vector.push_back(net_link);
         m_router_ptr_vector[dest]->addInPort(net_link);
         m_router_ptr_vector[src]->addOutPort(net_link, routing_table_entry,
-                                             link_weight);
+                                             link->m_weight);
     }         else {
         fatal("Fatal Error:: Reconfiguration not allowed here");
         // do nothing
index b04e649df9e9a6d53b0a4e76b3e4f1a7c3084347..a89a70ba753422a77f69856e8bf59b1eb07ad42b 100644 (file)
@@ -89,15 +89,18 @@ class GarnetNetwork : public BaseGarnetNetwork
     void reset();
 
     // Methods used by Topology to setup the network
-    void makeOutLink(SwitchID src, NodeID dest,
-        const NetDest& routing_table_entry, int link_latency,
-        int link_weight,  int bw_multiplier, bool isReconfiguration);
-    void makeInLink(SwitchID src, NodeID dest,
-        const NetDest& routing_table_entry, int link_latency,
-        int bw_multiplier, bool isReconfiguration);
-    void makeInternalLink(SwitchID src, NodeID dest,
-        const NetDest& routing_table_entry, int link_latency,
-        int link_weight, int bw_multiplier, bool isReconfiguration);
+    void makeOutLink(SwitchID src, NodeID dest, BasicLink* link, 
+                     LinkDirection direction, 
+                     const NetDest& routing_table_entry, 
+                     bool isReconfiguration);
+    void makeInLink(NodeID src, SwitchID dest, BasicLink* link, 
+                    LinkDirection direction, 
+                    const NetDest& routing_table_entry, 
+                    bool isReconfiguration);
+    void makeInternalLink(SwitchID src, SwitchID dest, BasicLink* link,
+                          LinkDirection direction, 
+                          const NetDest& routing_table_entry, 
+                          bool isReconfiguration);
 
   private:
     void checkNetworkAllocation(NodeID id, bool ordered, int network_num);
@@ -105,8 +108,6 @@ class GarnetNetwork : public BaseGarnetNetwork
     GarnetNetwork(const GarnetNetwork& obj);
     GarnetNetwork& operator=(const GarnetNetwork& obj);
 
-    // int m_virtual_networks;
-    // int m_nodes;
     int m_flits_received, m_flits_injected;
     double m_network_latency, m_queueing_latency;
 
@@ -120,7 +121,6 @@ class GarnetNetwork : public BaseGarnetNetwork
     std::vector<NetworkLink *> m_link_ptr_vector; // All links in network
     std::vector<NetworkInterface *> m_ni_ptr_vector; // All NI's in Network
 
-    // Topology* m_topology_ptr;
     Time m_ruby_start;
 };
 
diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetRouter.py b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetRouter.py
new file mode 100644 (file)
index 0000000..c35b7db
--- /dev/null
@@ -0,0 +1,44 @@
+# Copyright (c) 2008 Princeton University
+# 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 m5.proxy import *
+from BasicRouter import BasicRouter
+
+class GarnetRouter(BasicRouter):
+    type = 'GarnetRouter'
+    cxx_class = 'Router'
+    vcs_per_class = Param.Int(Parent.vcs_per_class,
+                              "virtual channels per message class")
+    virt_nets = Param.Int(Parent.number_of_virtual_networks,
+                          "number of virtual networks")
+    flit_width = Param.Int(Parent.flit_size, "flit width == flit size")
+
+
index 8badcb8124fbca023fe67bb4a1bca80590b5c4e0..c6584700aa1e74a839601cee1aca01ba775e90fe 100644 (file)
 #include "mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.hh"
 #include "mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh"
 
-NetworkLink::NetworkLink(int id, int latency, GarnetNetwork *net_ptr)
+NetworkLink::NetworkLink(const Params *p)
+    : SimObject(p)
 {
-    m_id = id;
     linkBuffer = new flitBuffer();
     m_in_port = 0;
     m_out_port = 0;
     m_link_utilized = 0;
-    m_net_ptr = net_ptr;
-    m_latency = latency;
-    int num_net = net_ptr->getNumberOfVirtualNetworks();
-    int num_vc = m_net_ptr->getVCsPerClass();
+    m_latency = p->link_latency;
+    m_id = p->link_id;
+    int num_net = p->virt_nets;
+    int num_vc = p->vcs_per_class;
     m_vc_load.resize(num_net * num_vc);
 
     for (int i = 0; i < num_net * num_vc; i++)
@@ -158,3 +158,9 @@ NetworkLink::consumeLink()
 {
     return linkBuffer->getTopFlit();
 }
+
+NetworkLink *
+NetworkLinkParams::create()
+{
+    return new NetworkLink(this);
+}
index cf2903a196bbbb4acaff346f13b621b00815419e..5b0cd5aae937eef005a65f36718ee3a1ba7e4c1c 100644 (file)
 #include "mem/ruby/network/garnet/flexible-pipeline/FlexibleConsumer.hh"
 #include "mem/ruby/network/garnet/flexible-pipeline/flitBuffer.hh"
 #include "mem/ruby/network/garnet/NetworkHeader.hh"
+#include "params/NetworkLink.hh"
+#include "sim/sim_object.hh"
 
 class GarnetNetwork;
 
-class NetworkLink : public FlexibleConsumer
+class NetworkLink : public SimObject, public FlexibleConsumer
 {
   public:
-    NetworkLink();
-    NetworkLink(int id, int latency, GarnetNetwork *net_ptr);
+    typedef NetworkLinkParams Params;
+    NetworkLink(const Params *p);
     ~NetworkLink();
 
     void setLinkConsumer(FlexibleConsumer *consumer);
@@ -70,6 +72,11 @@ class NetworkLink : public FlexibleConsumer
     double getLinkUtilization();
     std::vector<int> getVcLoad();
 
+    void init_net_ptr(GarnetNetwork* net_ptr) 
+    { 
+        m_net_ptr = net_ptr; 
+    }
+
   protected:
     int m_id, m_latency;
     int m_in_port, m_out_port;
index 31ecf96f96262af21b3de7fb6ce29fb096becedd..51af50b7dd7142cd19c8506e90fbcd22459b96c5 100644 (file)
 using namespace std;
 using m5::stl_helpers::deletePointers;
 
-Router::Router(int id, GarnetNetwork *network_ptr)
+Router::Router(const Params *p)
+    : BasicRouter(p)
 {
-    m_id = id;
-    m_net_ptr = network_ptr;
-    m_virtual_networks = m_net_ptr->getNumberOfVirtualNetworks();
-    m_vc_per_vnet = m_net_ptr->getVCsPerClass();
+    m_id = p->router_id;
+    m_virtual_networks = p->virt_nets;
+    m_vc_per_vnet = p->vcs_per_class;
     m_round_robin_inport = 0;
     m_round_robin_start = 0;
-    m_num_vcs = m_vc_per_vnet*m_virtual_networks;
+    m_num_vcs = m_vc_per_vnet * m_virtual_networks;
     m_vc_arbiter = new VCarbiter(this);
 }
 
@@ -440,3 +440,9 @@ Router::print(ostream& out) const
 {
     out << "[Router]";
 }
+
+Router *
+GarnetRouterParams::create()
+{
+    return new Router(this);
+}
index 99b9cc1c3a260d2cc37839a295cca27bb4d728a8..e9b340c9368c528a4fa391a884eaec5469a0232f 100644 (file)
@@ -35,6 +35,7 @@
 #include <vector>
 
 #include "mem/ruby/common/NetDest.hh"
+#include "mem/ruby/network/BasicRouter.hh"
 #include "mem/ruby/network/garnet/flexible-pipeline/FlexibleConsumer.hh"
 #include "mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.hh"
 #include "mem/ruby/network/garnet/flexible-pipeline/InVcState.hh"
 #include "mem/ruby/network/garnet/flexible-pipeline/OutVcState.hh"
 #include "mem/ruby/network/garnet/flexible-pipeline/flitBuffer.hh"
 #include "mem/ruby/network/garnet/NetworkHeader.hh"
+#include "params/GarnetRouter.hh"
 
 class VCarbiter;
 
-class Router : public FlexibleConsumer
+class Router : public BasicRouter, public FlexibleConsumer
 {
   public:
-    Router(int id, GarnetNetwork *network_ptr);
+    typedef GarnetRouterParams Params;
+    Router(const Params *p);
 
     ~Router();
 
@@ -67,6 +70,11 @@ class Router : public FlexibleConsumer
     void printConfig(std::ostream& out) const;
     void print(std::ostream& out) const;
 
+    void init_net_ptr(GarnetNetwork* net_ptr) 
+    { 
+        m_net_ptr = net_ptr; 
+    }
+
   private:
     int m_id;
     int m_virtual_networks, m_num_vcs, m_vc_per_vnet;
index fa23c02d6c116694954e9f25cf092ac7c31ce5a8..03f4e3fdb3becba164580c3ce074cc23662294b8 100644 (file)
@@ -33,8 +33,11 @@ Import('*')
 if not env['RUBY']:
     Return()
 
+SimObject('GarnetLink.py')
 SimObject('GarnetNetwork.py')
+SimObject('GarnetRouter.py')
 
+Source('GarnetLink.cc')
 Source('GarnetNetwork.cc')
 Source('InVcState.cc')
 Source('NetworkInterface.cc')
index 81d611f63edbe0e6bdf7587d9024ceff3748e161..2b77c2ef680346034c2270822694bbb8ac446942 100644 (file)
@@ -231,7 +231,6 @@ NetworkLink_d::calculate_power()
     OrionLink* orion_link_ptr;
     static double freq_Hz;
     double link_length;
-    int channel_width;
 
     // Initialization
     const string cfg_fn = "src/mem/ruby/network/orion/router.cfg";
@@ -239,17 +238,19 @@ NetworkLink_d::calculate_power()
     freq_Hz = orion_cfg_ptr->get<double>("FREQUENCY");
 
     link_length = orion_cfg_ptr->get<double>("LINK_LENGTH");
-    channel_width = m_net_ptr->getFlitSize();
 
     orion_link_ptr = new OrionLink(
         link_length,
         channel_width    /* channel width */,
         orion_cfg_ptr);
 
-
-    // Dynamic Power
-    double sim_cycles =
-        (double)(g_eventQueue_ptr->getTime() - m_net_ptr->getRubyStartTime());
+//
+//  NOTE!  I believe this calculation will be moved to McPAT, thus this
+//  reference to the net_ptr can be removed
+//
+//    // Dynamic Power
+    double sim_cycles = 0.0;
+//         (double)(g_eventQueue_ptr->getTime() - m_net_ptr->getRubyStartTime());
 
     double Plink_dyn = orion_link_ptr->calc_dynamic_energy(channel_width/2)*
         (m_link_utilized/ sim_cycles)*freq_Hz;
index 879ae2f7f72d7e9307e96d6259fd63519fb5a501..15107b17fc0c493c7915fe54b4be71c7bba8a5ce 100644 (file)
@@ -35,6 +35,7 @@
 #include "mem/protocol/TopologyType.hh"
 #include "mem/ruby/buffers/MessageBuffer.hh"
 #include "mem/ruby/common/NetDest.hh"
+#include "mem/ruby/network/BasicLink.hh"
 #include "mem/ruby/network/simple/SimpleNetwork.hh"
 #include "mem/ruby/network/simple/Switch.hh"
 #include "mem/ruby/network/simple/Throttle.hh"
@@ -133,9 +134,10 @@ SimpleNetwork::~SimpleNetwork()
 
 // From a switch to an endpoint node
 void
-SimpleNetwork::makeOutLink(SwitchID src, NodeID dest,
-    const NetDest& routing_table_entry, int link_latency, int link_weight,
-    int bw_multiplier, bool isReconfiguration)
+SimpleNetwork::makeOutLink(SwitchID src, NodeID dest, BasicLink* link, 
+                           LinkDirection direction, 
+                           const NetDest& routing_table_entry, 
+                           bool isReconfiguration)
 {
     assert(dest < m_nodes);
     assert(src < m_switch_ptr_vector.size());
@@ -147,15 +149,19 @@ SimpleNetwork::makeOutLink(SwitchID src, NodeID dest,
     }
 
     m_switch_ptr_vector[src]->addOutPort(m_fromNetQueues[dest],
-        routing_table_entry, link_latency, bw_multiplier);
+                                         routing_table_entry,
+                                         link->m_latency,
+                                         link->m_bw_multiplier);
+
     m_endpoint_switches[dest] = m_switch_ptr_vector[src];
 }
 
 // From an endpoint node to a switch
 void
-SimpleNetwork::makeInLink(NodeID src, SwitchID dest,
-    const NetDest& routing_table_entry, int link_latency, int bw_multiplier,
-    bool isReconfiguration)
+SimpleNetwork::makeInLink(NodeID src, SwitchID dest, BasicLink* link, 
+                          LinkDirection direction, 
+                          const NetDest& routing_table_entry, 
+                          bool isReconfiguration)
 {
     assert(src < m_nodes);
     if (isReconfiguration) {
@@ -168,9 +174,10 @@ SimpleNetwork::makeInLink(NodeID src, SwitchID dest,
 
 // From a switch to a switch
 void
-SimpleNetwork::makeInternalLink(SwitchID src, SwitchID dest,
-    const NetDest& routing_table_entry, int link_latency, int link_weight,
-    int bw_multiplier, bool isReconfiguration)
+SimpleNetwork::makeInternalLink(SwitchID src, SwitchID dest, BasicLink* link, 
+                                LinkDirection direction, 
+                                const NetDest& routing_table_entry,
+                                bool isReconfiguration)
 {
     if (isReconfiguration) {
         m_switch_ptr_vector[src]->reconfigureOutPort(routing_table_entry);
@@ -193,7 +200,8 @@ SimpleNetwork::makeInternalLink(SwitchID src, SwitchID dest,
     // Connect it to the two switches
     m_switch_ptr_vector[dest]->addInPort(queues);
     m_switch_ptr_vector[src]->addOutPort(queues, routing_table_entry,
-        link_latency, bw_multiplier);
+                                         link->m_latency, 
+                                         link->m_bw_multiplier);
 }
 
 void
index 2a791ab87289af53ffab891e283986200b92c5e3..13a4b173ef0278e01e9ee0cc6515d9855629db1b 100644 (file)
@@ -70,15 +70,18 @@ class SimpleNetwork : public Network
     int getNumNodes() {return m_nodes; }
 
     // Methods used by Topology to setup the network
-    void makeOutLink(SwitchID src, NodeID dest,
-        const NetDest& routing_table_entry, int link_latency, int link_weight,
-        int bw_multiplier, bool isReconfiguration);
-    void makeInLink(SwitchID src, NodeID dest,
-        const NetDest& routing_table_entry, int link_latency,
-        int bw_multiplier, bool isReconfiguration);
-    void makeInternalLink(SwitchID src, NodeID dest,
-        const NetDest& routing_table_entry, int link_latency, int link_weight,
-        int bw_multiplier, bool isReconfiguration);
+    void makeOutLink(SwitchID src, NodeID dest, BasicLink* link, 
+                     LinkDirection direction, 
+                     const NetDest& routing_table_entry, 
+                     bool isReconfiguration);
+    void makeInLink(NodeID src, SwitchID dest, BasicLink* link, 
+                    LinkDirection direction, 
+                    const NetDest& routing_table_entry, 
+                    bool isReconfiguration);
+    void makeInternalLink(SwitchID src, SwitchID dest, BasicLink* link,
+                          LinkDirection direction, 
+                          const NetDest& routing_table_entry, 
+                          bool isReconfiguration);
 
     void print(std::ostream& out) const;
 
index 77a6fd6f2a232dee5ce06a5ebcf3991e74392acb..8aa6c350413b1e5bcbed8a0faa0a49fadb6538a5 100644 (file)
@@ -32,12 +32,19 @@ from m5.objects import *
 class Crossbar(Topology):
     description='Crossbar'
 
-def makeTopology(nodes, options):
-    ext_links = [ExtLink(ext_node=n, int_node=i)
+def makeTopology(nodes, options, IntLink, ExtLink, Router):
+    # Create an individual router for each controller plus one more for the
+    # centralized crossbar.  The large numbers of routers are needed because
+    # external links do not model outgoing bandwidth in the simple network, but
+    # internal links do.
+    routers = [Router(router_id=i) for i in range(len(nodes)+1)]
+    ext_links = [ExtLink(link_id=i, ext_node=n, int_node=routers[i])
                  for (i, n) in enumerate(nodes)]
-    xbar = len(nodes) # node ID for crossbar switch
-    int_links = [IntLink(node_a=i, node_b=xbar) for i in range(len(nodes))]
+    link_count = len(nodes)
+    xbar = routers[len(nodes)] # the crossbar router is the last router created
+    int_links = [IntLink(link_id=(link_count+i), node_a=routers[i], node_b=xbar)
+                 for i in range(len(nodes))]
     return Crossbar(ext_links=ext_links, int_links=int_links,
-                    num_int_nodes=len(nodes)+1)
+                    routers=routers)
 
 
index d9ddc7b17dbd94421952277839a72024a91be314..20f3bba317e5d9e71bbb0bafc93161ec455566ad 100644 (file)
@@ -34,7 +34,7 @@ class Mesh(Topology):
 
 # Makes a generic mesh assuming an equal number of cache and directory cntrls
 
-def makeTopology(nodes, options):
+def makeTopology(nodes, options, IntLink, ExtLink, Router):
 
     num_routers = options.num_cpus
     num_rows = options.mesh_rows
@@ -46,6 +46,12 @@ def makeTopology(nodes, options):
     num_columns = int(num_routers / num_rows)
     assert(num_columns * num_rows == num_routers)
 
+    # Create the routers in the mesh
+    routers = [Router(router_id=i) for i in range(num_routers)]
+
+    # link counter to set unique link ids
+    link_count = 0
+
     # Add all but the remainder nodes to the list of nodes to be uniformly
     # distributed across the network.
     network_nodes = []
@@ -61,14 +67,18 @@ def makeTopology(nodes, options):
     for (i, n) in enumerate(network_nodes):
         cntrl_level, router_id = divmod(i, num_routers)
         assert(cntrl_level < cntrls_per_router)
-        ext_links.append(ExtLink(ext_node=n, int_node=router_id))
+        ext_links.append(ExtLink(link_id=link_count, ext_node=n,
+                                 int_node=routers[router_id]))
+        link_count += 1
 
     # Connect the remainding nodes to router 0.  These should only be
     # DMA nodes.
     for (i, node) in enumerate(remainder_nodes):
         assert(node.type == 'DMA_Controller')
         assert(i < remainder)
-        ext_links.append(ExtLink(ext_node=node, int_node=0))
+        ext_links.append(ExtLink(link_id=link_count, ext_node=node,
+                                 int_node=routers[0]))
+        link_count += 1
 
     # Create the mesh links.  First row (east-west) links then column
     # (north-south) links
@@ -78,18 +88,22 @@ def makeTopology(nodes, options):
             if (col + 1 < num_columns):
                 east_id = col + (row * num_columns)
                 west_id = (col + 1) + (row * num_columns)
-                int_links.append(IntLink(node_a=east_id,
-                                         node_b=west_id,
+                int_links.append(IntLink(link_id=link_count,
+                                         node_a=routers[east_id],
+                                         node_b=routers[west_id],
                                          weight=1))
+                link_count += 1
+                
     for col in xrange(num_columns):
         for row in xrange(num_rows):
             if (row + 1 < num_rows):
                 north_id = col + (row * num_columns)
                 south_id = col + ((row + 1) * num_columns)
-                int_links.append(IntLink(node_a=north_id,
-                                         node_b=south_id,
+                int_links.append(IntLink(link_id=link_count,
+                                         node_a=routers[north_id],
+                                         node_b=routers[south_id],
                                          weight=2))
-
+                link_count += 1
     return Mesh(ext_links=ext_links,
                 int_links=int_links,
-                num_int_nodes=num_routers)
+                routers=routers)
index e994ad1f99a7ba303a417988c93978a448af2ec3..1234d61c527fa06ea50387d78bcc065185759fbb 100644 (file)
@@ -37,7 +37,7 @@ class MeshDirCorners(Topology):
 # configurations.  The network specified is similar to GEMS old file
 # specified network.
 
-def makeTopology(nodes, options):
+def makeTopology(nodes, options, IntLink, ExtLink, Router):
     num_routers = options.num_cpus
     num_rows = options.mesh_rows
 
@@ -65,28 +65,39 @@ def makeTopology(nodes, options):
     assert(remainder == 0)
     assert(len(dir_nodes) == 4)
 
+    # Create the routers in the mesh
+    routers = [Router(router_id=i) for i in range(num_routers)]
+
+    # link counter to set unique link ids
+    link_count = 0
+
     # Connect each cache controller to the appropriate router
     ext_links = []
     for (i, n) in enumerate(cache_nodes):
         cntrl_level, router_id = divmod(i, num_routers)
         assert(cntrl_level < caches_per_router)
-        ext_links.append(ExtLink(ext_node=n, int_node=router_id))
+        ext_links.append(ExtLink(link_id=link_count, ext_node=n,
+                                 int_node=routers[router_id]))
+        link_count += 1
 
     # Connect the dir nodes to the corners.
-    ext_links.append(ExtLink(ext_node=dir_nodes[0], int_node=0))
-    ext_links.append(ExtLink(ext_node=dir_nodes[1],
-                             int_node=(num_columns - 1)))
-
-    ext_links.append(ExtLink(ext_node=dir_nodes[2],
-                             int_node=(num_routers - num_columns)))
-
-    ext_links.append(ExtLink(ext_node=dir_nodes[3],
-                             int_node=(num_routers - 1)))
+    ext_links.append(ExtLink(link_id=link_count, ext_node=dir_nodes[0],
+                             int_node=routers[0]))
+    link_count += 1
+    ext_links.append(ExtLink(link_id=link_count, ext_node=dir_nodes[1],
+                             int_node=routers[num_columns - 1]))
+    link_count += 1
+    ext_links.append(ExtLink(link_id=link_count, ext_node=dir_nodes[2],
+                             int_node=routers[num_routers - num_columns]))
+    link_count += 1
+    ext_links.append(ExtLink(link_id=link_count, ext_node=dir_nodes[3],
+                             int_node=routers[num_routers - 1]))
+    link_count += 1
 
     # Connect the dma nodes to router 0.  These should only be DMA nodes.
     for (i, node) in enumerate(dma_nodes):
         assert(node.type == 'DMA_Controller')
-        ext_links.append(ExtLink(ext_node=node, int_node=0))
+        ext_links.append(ExtLink(ext_node=node, int_node=routers[0]))
 
     # Create the mesh links.  First row (east-west) links then column
     # (north-south) links
@@ -96,19 +107,24 @@ def makeTopology(nodes, options):
             if (col + 1 < num_columns):
                 east_id = col + (row * num_columns)
                 west_id = (col + 1) + (row * num_columns)
-                int_links.append(IntLink(node_a=east_id,
-                                         node_b=west_id,
+                int_links.append(IntLink(link_id=link_count,
+                                         node_a=routers[east_id],
+                                         node_b=routers[west_id],
                                          weight=1))
+                link_count += 1
+                
     for col in xrange(num_columns):
         for row in xrange(num_rows):
             if (row + 1 < num_rows):
                 north_id = col + (row * num_columns)
                 south_id = col + ((row + 1) * num_columns)
-                int_links.append(IntLink(node_a=north_id,
-                                         node_b=south_id,
+                int_links.append(IntLink(link_id=link_count,
+                                         node_a=routers[north_id],
+                                         node_b=routers[south_id],
                                          weight=2))
+                link_count += 1
 
     return MeshDirCorners(ext_links=ext_links,
                           int_links=int_links,
-                          num_int_nodes=num_routers)
+                          routers=routers)
 
index 44e47c8ca81b760de07b7b595319533e00bfcd9e..fcfe104b3345d34fc2ab179c578eb25da9c88441 100644 (file)
@@ -47,6 +47,7 @@ class AbstractController : public SimObject, public Consumer
   public:
     typedef RubyControllerParams Params;
     AbstractController(const Params *p) : SimObject(p) {}
+    const Params *params() const { return (const Params *)_params; }
 
     // returns the number of controllers created of the specific subtype
     //  virtual int getNumberOfControllers() const = 0;
index dc65e7f7e62b8a3e6213c62b546f71ffb0154512..a5ad45145ea5dc7fe596b3595d247eed55f9c04f 100644 (file)
@@ -35,6 +35,7 @@ class RubyController(SimObject):
     cxx_class = 'AbstractController'
     abstract = True
     version = Param.Int("")
+    cntrl_id = Param.Int("")
     transitions_per_cycle = \
         Param.Int(32, "no. of  SLICC state machine transitions per cycle")
     buffer_size = Param.Int(0, "max buffer size 0 means infinite")