From 40bcbf42539fec83628f2ae2627238adff27f62c Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Thu, 28 Apr 2011 17:18:14 -0700 Subject: [PATCH] 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 --- configs/ruby/MESI_CMP_directory.py | 14 ++ configs/ruby/MI_example.py | 11 + configs/ruby/MOESI_CMP_directory.py | 14 ++ configs/ruby/MOESI_CMP_token.py | 14 ++ configs/ruby/MOESI_hammer.py | 11 + configs/ruby/Network_test.py | 8 + configs/ruby/Ruby.py | 34 ++- src/mem/protocol/RubySlicc_Exports.sm | 6 + src/mem/ruby/network/BasicLink.cc | 80 +++++++ src/mem/ruby/network/BasicLink.hh | 96 ++++++++ src/mem/ruby/network/BasicLink.py | 50 ++++ src/mem/ruby/network/BasicRouter.cc | 52 +++++ src/mem/ruby/network/BasicRouter.hh | 67 ++++++ src/mem/ruby/network/BasicRouter.py | 35 +++ src/mem/ruby/network/Network.hh | 22 +- src/mem/ruby/network/Network.py | 25 +- src/mem/ruby/network/SConscript | 4 + src/mem/ruby/network/Topology.cc | 216 +++++++++--------- src/mem/ruby/network/Topology.hh | 58 ++--- .../garnet/fixed-pipeline/CreditLink_d.hh | 6 +- .../garnet/fixed-pipeline/GarnetLink_d.cc | 83 +++++++ .../garnet/fixed-pipeline/GarnetLink_d.hh | 92 ++++++++ .../garnet/fixed-pipeline/GarnetLink_d.py | 85 +++++++ .../garnet/fixed-pipeline/GarnetNetwork_d.cc | 79 ++++--- .../garnet/fixed-pipeline/GarnetNetwork_d.hh | 21 +- .../garnet/fixed-pipeline/GarnetRouter_d.py | 44 ++++ .../garnet/fixed-pipeline/NetworkLink_d.cc | 30 ++- .../garnet/fixed-pipeline/NetworkLink_d.hh | 10 +- .../network/garnet/fixed-pipeline/Router_d.cc | 23 +- .../network/garnet/fixed-pipeline/Router_d.hh | 13 +- .../network/garnet/fixed-pipeline/SConscript | 3 + .../garnet/flexible-pipeline/GarnetLink.cc | 78 +++++++ .../garnet/flexible-pipeline/GarnetLink.hh | 89 ++++++++ .../garnet/flexible-pipeline/GarnetLink.py | 68 ++++++ .../garnet/flexible-pipeline/GarnetNetwork.cc | 61 +++-- .../garnet/flexible-pipeline/GarnetNetwork.hh | 24 +- .../garnet/flexible-pipeline/GarnetRouter.py | 44 ++++ .../garnet/flexible-pipeline/NetworkLink.cc | 18 +- .../garnet/flexible-pipeline/NetworkLink.hh | 13 +- .../garnet/flexible-pipeline/Router.cc | 18 +- .../garnet/flexible-pipeline/Router.hh | 12 +- .../garnet/flexible-pipeline/SConscript | 3 + src/mem/ruby/network/orion/NetworkPower.cc | 13 +- src/mem/ruby/network/simple/SimpleNetwork.cc | 30 ++- src/mem/ruby/network/simple/SimpleNetwork.hh | 21 +- src/mem/ruby/network/topologies/Crossbar.py | 17 +- src/mem/ruby/network/topologies/Mesh.py | 32 ++- .../ruby/network/topologies/MeshDirCorners.py | 50 ++-- .../slicc_interface/AbstractController.hh | 1 + src/mem/ruby/slicc_interface/Controller.py | 1 + 50 files changed, 1531 insertions(+), 368 deletions(-) create mode 100644 src/mem/ruby/network/BasicLink.cc create mode 100644 src/mem/ruby/network/BasicLink.hh create mode 100644 src/mem/ruby/network/BasicLink.py create mode 100644 src/mem/ruby/network/BasicRouter.cc create mode 100644 src/mem/ruby/network/BasicRouter.hh create mode 100644 src/mem/ruby/network/BasicRouter.py create mode 100644 src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.cc create mode 100644 src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.hh create mode 100644 src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.py create mode 100644 src/mem/ruby/network/garnet/fixed-pipeline/GarnetRouter_d.py create mode 100644 src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.cc create mode 100644 src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.hh create mode 100644 src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.py create mode 100644 src/mem/ruby/network/garnet/flexible-pipeline/GarnetRouter.py 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 +#include +#include + +#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 +#include +#include + +#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 #include +#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* 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::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::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::const_iterator i = params()->int_links.begin(); + for (vector::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; - // 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); + // Store the IntLink pointers for later + m_int_link_vector.push_back(int_link); + + 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::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 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 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 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 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 #include +#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 > Matrix; -class Link : public SimObject +struct LinkEntry { - public: - typedef LinkParams Params; - Link(const Params *p) : SimObject(p) {} - const Params *params() const { return (const Params *)_params; } + BasicLink *link; + LinkDirection direction; }; -class ExtLink : public Link -{ - public: - typedef ExtLinkParams Params; - ExtLink(const Params *p) : Link(p) {} - const Params *params() const { return (const Params *)_params; } -}; - -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, 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 > &nodePairs, - // std::vector &latencies, std::vector &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 m_controller_vector; - - std::vector m_links_src_vector; - std::vector m_links_dest_vector; - std::vector m_links_latency_vector; - std::vector m_links_weight_vector; - std::vector m_bw_multiplier_vector; + std::vector m_ext_link_vector; + std::vector m_int_link_vector; Matrix m_component_latencies; Matrix m_component_inter_switches; + + LinkMap m_link_map; + std::vector 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 +#include +#include + +#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::const_iterator i = + m_topology_ptr->params()->routers.begin(); + i != m_topology_ptr->params()->routers.end(); ++i) { + Router_d* router = safe_cast(*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::const_iterator i = m_router_ptr_vector.begin(); + i != m_router_ptr_vector.end(); ++i) { + Router_d* router = safe_cast(*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; icreateLinks(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(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(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(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 #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& get_inputUnit_ref() { return m_input_unit; } std::vector& 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 +#include +#include + +#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::const_iterator i = + m_topology_ptr->params()->routers.begin(); + i != m_topology_ptr->params()->routers.end(); ++i) { + Router* router = safe_cast(*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::const_iterator i = m_router_ptr_vector.begin(); + i != m_router_ptr_vector.end(); ++i) { + Router* router = safe_cast(*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(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(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(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 m_link_ptr_vector; // All links in network std::vector 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 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 #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("FREQUENCY"); link_length = orion_cfg_ptr->get("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")