summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Beckmann <Brad.Beckmann@amd.com>2011-04-28 17:18:14 -0700
committerBrad Beckmann <Brad.Beckmann@amd.com>2011-04-28 17:18:14 -0700
commit40bcbf42539fec83628f2ae2627238adff27f62c (patch)
tree993083e3b6e5661697261e81869bf40e17027826
parentbc5eb596053f7f69c88f8218f20709d94b2a331c (diff)
downloadgem5-40bcbf42539fec83628f2ae2627238adff27f62c.tar.xz
network: convert links & switches to first class C++ SimObjects
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
-rw-r--r--configs/ruby/MESI_CMP_directory.py14
-rw-r--r--configs/ruby/MI_example.py11
-rw-r--r--configs/ruby/MOESI_CMP_directory.py14
-rw-r--r--configs/ruby/MOESI_CMP_token.py14
-rw-r--r--configs/ruby/MOESI_hammer.py11
-rw-r--r--configs/ruby/Network_test.py8
-rw-r--r--configs/ruby/Ruby.py34
-rw-r--r--src/mem/protocol/RubySlicc_Exports.sm6
-rw-r--r--src/mem/ruby/network/BasicLink.cc80
-rw-r--r--src/mem/ruby/network/BasicLink.hh96
-rw-r--r--src/mem/ruby/network/BasicLink.py50
-rw-r--r--src/mem/ruby/network/BasicRouter.cc52
-rw-r--r--src/mem/ruby/network/BasicRouter.hh67
-rw-r--r--src/mem/ruby/network/BasicRouter.py35
-rw-r--r--src/mem/ruby/network/Network.hh22
-rw-r--r--src/mem/ruby/network/Network.py25
-rw-r--r--src/mem/ruby/network/SConscript4
-rw-r--r--src/mem/ruby/network/Topology.cc216
-rw-r--r--src/mem/ruby/network/Topology.hh58
-rw-r--r--src/mem/ruby/network/garnet/fixed-pipeline/CreditLink_d.hh6
-rw-r--r--src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.cc83
-rw-r--r--src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.hh92
-rw-r--r--src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.py85
-rw-r--r--src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc79
-rw-r--r--src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh21
-rw-r--r--src/mem/ruby/network/garnet/fixed-pipeline/GarnetRouter_d.py44
-rw-r--r--src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.cc30
-rw-r--r--src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh10
-rw-r--r--src/mem/ruby/network/garnet/fixed-pipeline/Router_d.cc23
-rw-r--r--src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh13
-rw-r--r--src/mem/ruby/network/garnet/fixed-pipeline/SConscript3
-rw-r--r--src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.cc78
-rw-r--r--src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.hh89
-rw-r--r--src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.py68
-rw-r--r--src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc61
-rw-r--r--src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.hh24
-rw-r--r--src/mem/ruby/network/garnet/flexible-pipeline/GarnetRouter.py44
-rw-r--r--src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.cc18
-rw-r--r--src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh13
-rw-r--r--src/mem/ruby/network/garnet/flexible-pipeline/Router.cc18
-rw-r--r--src/mem/ruby/network/garnet/flexible-pipeline/Router.hh12
-rw-r--r--src/mem/ruby/network/garnet/flexible-pipeline/SConscript3
-rw-r--r--src/mem/ruby/network/orion/NetworkPower.cc13
-rw-r--r--src/mem/ruby/network/simple/SimpleNetwork.cc30
-rw-r--r--src/mem/ruby/network/simple/SimpleNetwork.hh21
-rw-r--r--src/mem/ruby/network/topologies/Crossbar.py17
-rw-r--r--src/mem/ruby/network/topologies/Mesh.py32
-rw-r--r--src/mem/ruby/network/topologies/MeshDirCorners.py50
-rw-r--r--src/mem/ruby/slicc_interface/AbstractController.hh1
-rw-r--r--src/mem/ruby/slicc_interface/Controller.py1
50 files changed, 1531 insertions, 368 deletions
diff --git a/configs/ruby/MESI_CMP_directory.py b/configs/ruby/MESI_CMP_directory.py
index 2f7faab52..4bd969be5 100644
--- a/configs/ruby/MESI_CMP_directory.py
+++ b/configs/ruby/MESI_CMP_directory.py
@@ -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 + \
diff --git a/configs/ruby/MI_example.py b/configs/ruby/MI_example.py
index 062748eef..5f5703d4e 100644
--- a/configs/ruby/MI_example.py
+++ b/configs/ruby/MI_example.py
@@ -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)
diff --git a/configs/ruby/MOESI_CMP_directory.py b/configs/ruby/MOESI_CMP_directory.py
index ff7ea0cc5..15558a62d 100644
--- a/configs/ruby/MOESI_CMP_directory.py
+++ b/configs/ruby/MOESI_CMP_directory.py
@@ -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 + \
diff --git a/configs/ruby/MOESI_CMP_token.py b/configs/ruby/MOESI_CMP_token.py
index 72721058b..5b6e21f33 100644
--- a/configs/ruby/MOESI_CMP_token.py
+++ b/configs/ruby/MOESI_CMP_token.py
@@ -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 + \
diff --git a/configs/ruby/MOESI_hammer.py b/configs/ruby/MOESI_hammer.py
index 3804a58b1..4a0391264 100644
--- a/configs/ruby/MOESI_hammer.py
+++ b/configs/ruby/MOESI_hammer.py
@@ -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)
diff --git a/configs/ruby/Network_test.py b/configs/ruby/Network_test.py
index fe1559f53..75ec9099e 100644
--- a/configs/ruby/Network_test.py
+++ b/configs/ruby/Network_test.py
@@ -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)
diff --git a/configs/ruby/Ruby.py b/configs/ruby/Ruby.py
index e5d3c4a7c..7f32829d6 100644
--- a/configs/ruby/Ruby.py
+++ b/configs/ruby/Ruby.py
@@ -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.
diff --git a/src/mem/protocol/RubySlicc_Exports.sm b/src/mem/protocol/RubySlicc_Exports.sm
index 5fb5f9912..ccd3aeb7f 100644
--- a/src/mem/protocol/RubySlicc_Exports.sm
+++ b/src/mem/protocol/RubySlicc_Exports.sm
@@ -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
index 000000000..907a04f39
--- /dev/null
+++ b/src/mem/ruby/network/BasicLink.cc
@@ -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
index 000000000..c7359807f
--- /dev/null
+++ b/src/mem/ruby/network/BasicLink.hh
@@ -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
index 000000000..53df4d57e
--- /dev/null
+++ b/src/mem/ruby/network/BasicLink.py
@@ -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
index 000000000..a6972afe2
--- /dev/null
+++ b/src/mem/ruby/network/BasicRouter.cc
@@ -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
index 000000000..67dc21c65
--- /dev/null
+++ b/src/mem/ruby/network/BasicRouter.hh
@@ -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
index 000000000..0ff41c33c
--- /dev/null
+++ b/src/mem/ruby/network/BasicRouter.py
@@ -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")
diff --git a/src/mem/ruby/network/Network.hh b/src/mem/ruby/network/Network.hh
index 51be0105c..a33360e6a 100644
--- a/src/mem/ruby/network/Network.hh
+++ b/src/mem/ruby/network/Network.hh
@@ -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;
diff --git a/src/mem/ruby/network/Network.py b/src/mem/ruby/network/Network.py
index 530afcc45..c539f7191 100644
--- a/src/mem/ruby/network/Network.py
+++ b/src/mem/ruby/network/Network.py
@@ -29,32 +29,15 @@
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")
diff --git a/src/mem/ruby/network/SConscript b/src/mem/ruby/network/SConscript
index 079ecf9f6..3c3bcea06 100644
--- a/src/mem/ruby/network/SConscript
+++ b/src/mem/ruby/network/SConscript
@@ -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')
diff --git a/src/mem/ruby/network/Topology.cc b/src/mem/ruby/network/Topology.cc
index 61f3ad361..58af3811f 100644
--- a/src/mem/ruby/network/Topology.cc
+++ b/src/mem/ruby/network/Topology.cc
@@ -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);
-}
diff --git a/src/mem/ruby/network/Topology.hh b/src/mem/ruby/network/Topology.hh
index c92848d8f..7b7439686 100644
--- a/src/mem/ruby/network/Topology.hh
+++ b/src/mem/ruby/network/Topology.hh
@@ -44,42 +44,24 @@
#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&
diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/CreditLink_d.hh b/src/mem/ruby/network/garnet/fixed-pipeline/CreditLink_d.hh
index 779161336..e6c39475d 100644
--- a/src/mem/ruby/network/garnet/fixed-pipeline/CreditLink_d.hh
+++ b/src/mem/ruby/network/garnet/fixed-pipeline/CreditLink_d.hh
@@ -32,13 +32,13 @@
#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
index 000000000..da9249690
--- /dev/null
+++ b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.cc
@@ -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
index 000000000..cb2ae62dc
--- /dev/null
+++ b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.hh
@@ -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
index 000000000..941746cbc
--- /dev/null
+++ b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.py
@@ -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")
diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc
index 265023b7e..5aa9ceca8 100644
--- a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc
+++ b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc
@@ -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
diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh
index f403660ea..7c6e5f8e1 100644
--- a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh
+++ b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh
@@ -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
index 000000000..92e49b328
--- /dev/null
+++ b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetRouter_d.py
@@ -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")
+
+
diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.cc
index 72439a67b..38627b109 100644
--- a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.cc
+++ b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.cc
@@ -28,22 +28,20 @@
* 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);
+}
diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh
index a46c59f41..5da006c4d 100644
--- a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh
+++ b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh
@@ -38,16 +38,18 @@
#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;
diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.cc
index 15cddd3b7..5eefd52de 100644
--- a/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.cc
+++ b/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.cc
@@ -43,14 +43,13 @@
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);
+}
diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh b/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh
index 4c2b83312..ec44cc7b3 100644
--- a/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh
+++ b/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh
@@ -35,9 +35,11 @@
#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;
diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/SConscript b/src/mem/ruby/network/garnet/fixed-pipeline/SConscript
index d3cf45878..ae3b964de 100644
--- a/src/mem/ruby/network/garnet/fixed-pipeline/SConscript
+++ b/src/mem/ruby/network/garnet/fixed-pipeline/SConscript
@@ -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
index 000000000..270b1327e
--- /dev/null
+++ b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.cc
@@ -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
index 000000000..cd42378bf
--- /dev/null
+++ b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.hh
@@ -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
index 000000000..45c56fa9e
--- /dev/null
+++ b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.py
@@ -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")
diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc
index 8e919284a..16c56e95e 100644
--- a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc
+++ b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc
@@ -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
diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.hh b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.hh
index b04e649df..a89a70ba7 100644
--- a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.hh
+++ b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.hh
@@ -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
index 000000000..c35b7db38
--- /dev/null
+++ b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetRouter.py
@@ -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")
+
+
diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.cc b/src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.cc
index 8badcb812..c6584700a 100644
--- a/src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.cc
+++ b/src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.cc
@@ -31,17 +31,17 @@
#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);
+}
diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh b/src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh
index cf2903a19..5b0cd5aae 100644
--- a/src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh
+++ b/src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh
@@ -38,14 +38,16 @@
#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;
diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/Router.cc b/src/mem/ruby/network/garnet/flexible-pipeline/Router.cc
index 31ecf96f9..51af50b7d 100644
--- a/src/mem/ruby/network/garnet/flexible-pipeline/Router.cc
+++ b/src/mem/ruby/network/garnet/flexible-pipeline/Router.cc
@@ -39,15 +39,15 @@
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);
+}
diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/Router.hh b/src/mem/ruby/network/garnet/flexible-pipeline/Router.hh
index 99b9cc1c3..e9b340c93 100644
--- a/src/mem/ruby/network/garnet/flexible-pipeline/Router.hh
+++ b/src/mem/ruby/network/garnet/flexible-pipeline/Router.hh
@@ -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"
@@ -42,13 +43,15 @@
#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;
diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/SConscript b/src/mem/ruby/network/garnet/flexible-pipeline/SConscript
index fa23c02d6..03f4e3fdb 100644
--- a/src/mem/ruby/network/garnet/flexible-pipeline/SConscript
+++ b/src/mem/ruby/network/garnet/flexible-pipeline/SConscript
@@ -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')
diff --git a/src/mem/ruby/network/orion/NetworkPower.cc b/src/mem/ruby/network/orion/NetworkPower.cc
index 81d611f63..2b77c2ef6 100644
--- a/src/mem/ruby/network/orion/NetworkPower.cc
+++ b/src/mem/ruby/network/orion/NetworkPower.cc
@@ -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;
diff --git a/src/mem/ruby/network/simple/SimpleNetwork.cc b/src/mem/ruby/network/simple/SimpleNetwork.cc
index 879ae2f7f..15107b17f 100644
--- a/src/mem/ruby/network/simple/SimpleNetwork.cc
+++ b/src/mem/ruby/network/simple/SimpleNetwork.cc
@@ -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
diff --git a/src/mem/ruby/network/simple/SimpleNetwork.hh b/src/mem/ruby/network/simple/SimpleNetwork.hh
index 2a791ab87..13a4b173e 100644
--- a/src/mem/ruby/network/simple/SimpleNetwork.hh
+++ b/src/mem/ruby/network/simple/SimpleNetwork.hh
@@ -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;
diff --git a/src/mem/ruby/network/topologies/Crossbar.py b/src/mem/ruby/network/topologies/Crossbar.py
index 77a6fd6f2..8aa6c3504 100644
--- a/src/mem/ruby/network/topologies/Crossbar.py
+++ b/src/mem/ruby/network/topologies/Crossbar.py
@@ -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)
diff --git a/src/mem/ruby/network/topologies/Mesh.py b/src/mem/ruby/network/topologies/Mesh.py
index d9ddc7b17..20f3bba31 100644
--- a/src/mem/ruby/network/topologies/Mesh.py
+++ b/src/mem/ruby/network/topologies/Mesh.py
@@ -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)
diff --git a/src/mem/ruby/network/topologies/MeshDirCorners.py b/src/mem/ruby/network/topologies/MeshDirCorners.py
index e994ad1f9..1234d61c5 100644
--- a/src/mem/ruby/network/topologies/MeshDirCorners.py
+++ b/src/mem/ruby/network/topologies/MeshDirCorners.py
@@ -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)
diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh b/src/mem/ruby/slicc_interface/AbstractController.hh
index 44e47c8ca..fcfe104b3 100644
--- a/src/mem/ruby/slicc_interface/AbstractController.hh
+++ b/src/mem/ruby/slicc_interface/AbstractController.hh
@@ -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;
diff --git a/src/mem/ruby/slicc_interface/Controller.py b/src/mem/ruby/slicc_interface/Controller.py
index dc65e7f7e..a5ad45145 100644
--- a/src/mem/ruby/slicc_interface/Controller.py
+++ b/src/mem/ruby/slicc_interface/Controller.py
@@ -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")