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
This commit is contained in:
Brad Beckmann 2011-04-28 17:18:14 -07:00
parent bc5eb59605
commit 40bcbf4253
50 changed files with 1531 additions and 368 deletions

View file

@ -71,6 +71,8 @@ def create_system(options, system, piobus, dma_devices):
l2_bits = int(math.log(options.num_l2caches, 2)) l2_bits = int(math.log(options.num_l2caches, 2))
block_size_bits = int(math.log(options.cacheline_size, 2)) block_size_bits = int(math.log(options.cacheline_size, 2))
cntrl_count = 0
for i in xrange(options.num_cpus): for i in xrange(options.num_cpus):
# #
# First create the Ruby objects associated with this cpu # 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 cpu_seq.pio_port = piobus.port
l1_cntrl = L1Cache_Controller(version = i, l1_cntrl = L1Cache_Controller(version = i,
cntrl_id = cntrl_count,
sequencer = cpu_seq, sequencer = cpu_seq,
L1IcacheMemory = l1i_cache, L1IcacheMemory = l1i_cache,
L1DcacheMemory = l1d_cache, L1DcacheMemory = l1d_cache,
@ -105,6 +108,8 @@ def create_system(options, system, piobus, dma_devices):
cpu_sequencers.append(cpu_seq) cpu_sequencers.append(cpu_seq)
l1_cntrl_nodes.append(l1_cntrl) l1_cntrl_nodes.append(l1_cntrl)
cntrl_count += 1
l2_index_start = block_size_bits + l2_bits l2_index_start = block_size_bits + l2_bits
for i in xrange(options.num_l2caches): for i in xrange(options.num_l2caches):
@ -116,11 +121,14 @@ def create_system(options, system, piobus, dma_devices):
start_index_bit = l2_index_start) start_index_bit = l2_index_start)
l2_cntrl = L2Cache_Controller(version = i, l2_cntrl = L2Cache_Controller(version = i,
cntrl_id = cntrl_count,
L2cacheMemory = l2_cache) L2cacheMemory = l2_cache)
exec("system.l2_cntrl%d = l2_cntrl" % i) exec("system.l2_cntrl%d = l2_cntrl" % i)
l2_cntrl_nodes.append(l2_cntrl) l2_cntrl_nodes.append(l2_cntrl)
cntrl_count += 1
phys_mem_size = long(system.physmem.range.second) - \ phys_mem_size = long(system.physmem.range.second) - \
long(system.physmem.range.first) + 1 long(system.physmem.range.first) + 1
mem_module_size = phys_mem_size / options.num_dirs 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_size.value = mem_module_size
dir_cntrl = Directory_Controller(version = i, dir_cntrl = Directory_Controller(version = i,
cntrl_id = cntrl_count,
directory = \ directory = \
RubyDirectoryMemory(version = i, RubyDirectoryMemory(version = i,
size = \ size = \
@ -145,6 +154,8 @@ def create_system(options, system, piobus, dma_devices):
exec("system.dir_cntrl%d = dir_cntrl" % i) exec("system.dir_cntrl%d = dir_cntrl" % i)
dir_cntrl_nodes.append(dir_cntrl) dir_cntrl_nodes.append(dir_cntrl)
cntrl_count += 1
for i, dma_device in enumerate(dma_devices): for i, dma_device in enumerate(dma_devices):
# #
# Create the Ruby objects associated with the dma controller # Create the Ruby objects associated with the dma controller
@ -154,6 +165,7 @@ def create_system(options, system, piobus, dma_devices):
physmem = system.physmem) physmem = system.physmem)
dma_cntrl = DMA_Controller(version = i, dma_cntrl = DMA_Controller(version = i,
cntrl_id = cntrl_count,
dma_sequencer = dma_seq) dma_sequencer = dma_seq)
exec("system.dma_cntrl%d = dma_cntrl" % i) 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) exec("system.dma_cntrl%d.dma_sequencer.port = dma_device.dma" % i)
dma_cntrl_nodes.append(dma_cntrl) dma_cntrl_nodes.append(dma_cntrl)
cntrl_count += 1
all_cntrls = l1_cntrl_nodes + \ all_cntrls = l1_cntrl_nodes + \
l2_cntrl_nodes + \ l2_cntrl_nodes + \
dir_cntrl_nodes + \ dir_cntrl_nodes + \

View file

@ -63,6 +63,8 @@ def create_system(options, system, piobus, dma_devices):
# #
block_size_bits = int(math.log(options.cacheline_size, 2)) block_size_bits = int(math.log(options.cacheline_size, 2))
cntrl_count = 0
for i in xrange(options.num_cpus): for i in xrange(options.num_cpus):
# #
# First create the Ruby objects associated with this cpu # First create the Ruby objects associated with this cpu
@ -86,6 +88,7 @@ def create_system(options, system, piobus, dma_devices):
cpu_seq.pio_port = piobus.port cpu_seq.pio_port = piobus.port
l1_cntrl = L1Cache_Controller(version = i, l1_cntrl = L1Cache_Controller(version = i,
cntrl_id = cntrl_count,
sequencer = cpu_seq, sequencer = cpu_seq,
cacheMemory = cache) cacheMemory = cache)
@ -96,6 +99,8 @@ def create_system(options, system, piobus, dma_devices):
cpu_sequencers.append(cpu_seq) cpu_sequencers.append(cpu_seq)
l1_cntrl_nodes.append(l1_cntrl) l1_cntrl_nodes.append(l1_cntrl)
cntrl_count += 1
phys_mem_size = long(system.physmem.range.second) - \ phys_mem_size = long(system.physmem.range.second) - \
long(system.physmem.range.first) + 1 long(system.physmem.range.first) + 1
mem_module_size = phys_mem_size / options.num_dirs 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_size.value = mem_module_size
dir_cntrl = Directory_Controller(version = i, dir_cntrl = Directory_Controller(version = i,
cntrl_id = cntrl_count,
directory = \ directory = \
RubyDirectoryMemory( \ RubyDirectoryMemory( \
version = i, version = i,
@ -123,6 +129,8 @@ def create_system(options, system, piobus, dma_devices):
exec("system.dir_cntrl%d = dir_cntrl" % i) exec("system.dir_cntrl%d = dir_cntrl" % i)
dir_cntrl_nodes.append(dir_cntrl) dir_cntrl_nodes.append(dir_cntrl)
cntrl_count += 1
for i, dma_device in enumerate(dma_devices): for i, dma_device in enumerate(dma_devices):
# #
# Create the Ruby objects associated with the dma controller # Create the Ruby objects associated with the dma controller
@ -132,6 +140,7 @@ def create_system(options, system, piobus, dma_devices):
physmem = system.physmem) physmem = system.physmem)
dma_cntrl = DMA_Controller(version = i, dma_cntrl = DMA_Controller(version = i,
cntrl_id = cntrl_count,
dma_sequencer = dma_seq) dma_sequencer = dma_seq)
exec("system.dma_cntrl%d = dma_cntrl" % i) 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.dma_sequencer.port = dma_device.dma
dma_cntrl_nodes.append(dma_cntrl) dma_cntrl_nodes.append(dma_cntrl)
cntrl_count += 1
all_cntrls = l1_cntrl_nodes + dir_cntrl_nodes + dma_cntrl_nodes all_cntrls = l1_cntrl_nodes + dir_cntrl_nodes + dma_cntrl_nodes
return (cpu_sequencers, dir_cntrl_nodes, all_cntrls) return (cpu_sequencers, dir_cntrl_nodes, all_cntrls)

View file

@ -71,6 +71,8 @@ def create_system(options, system, piobus, dma_devices):
l2_bits = int(math.log(options.num_l2caches, 2)) l2_bits = int(math.log(options.num_l2caches, 2))
block_size_bits = int(math.log(options.cacheline_size, 2)) block_size_bits = int(math.log(options.cacheline_size, 2))
cntrl_count = 0
for i in xrange(options.num_cpus): for i in xrange(options.num_cpus):
# #
# First create the Ruby objects associated with this cpu # 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 cpu_seq.pio_port = piobus.port
l1_cntrl = L1Cache_Controller(version = i, l1_cntrl = L1Cache_Controller(version = i,
cntrl_id = cntrl_count,
sequencer = cpu_seq, sequencer = cpu_seq,
L1IcacheMemory = l1i_cache, L1IcacheMemory = l1i_cache,
L1DcacheMemory = l1d_cache, L1DcacheMemory = l1d_cache,
@ -104,6 +107,8 @@ def create_system(options, system, piobus, dma_devices):
cpu_sequencers.append(cpu_seq) cpu_sequencers.append(cpu_seq)
l1_cntrl_nodes.append(l1_cntrl) l1_cntrl_nodes.append(l1_cntrl)
cntrl_count += 1
l2_index_start = block_size_bits + l2_bits l2_index_start = block_size_bits + l2_bits
for i in xrange(options.num_l2caches): for i in xrange(options.num_l2caches):
@ -115,11 +120,14 @@ def create_system(options, system, piobus, dma_devices):
start_index_bit = l2_index_start) start_index_bit = l2_index_start)
l2_cntrl = L2Cache_Controller(version = i, l2_cntrl = L2Cache_Controller(version = i,
cntrl_id = cntrl_count,
L2cacheMemory = l2_cache) L2cacheMemory = l2_cache)
exec("system.l2_cntrl%d = l2_cntrl" % i) exec("system.l2_cntrl%d = l2_cntrl" % i)
l2_cntrl_nodes.append(l2_cntrl) l2_cntrl_nodes.append(l2_cntrl)
cntrl_count += 1
phys_mem_size = long(system.physmem.range.second) - \ phys_mem_size = long(system.physmem.range.second) - \
long(system.physmem.range.first) + 1 long(system.physmem.range.first) + 1
mem_module_size = phys_mem_size / options.num_dirs mem_module_size = phys_mem_size / options.num_dirs
@ -135,6 +143,7 @@ def create_system(options, system, piobus, dma_devices):
dir_size.value = mem_module_size dir_size.value = mem_module_size
dir_cntrl = Directory_Controller(version = i, dir_cntrl = Directory_Controller(version = i,
cntrl_id = cntrl_count,
directory = \ directory = \
RubyDirectoryMemory(version = i, RubyDirectoryMemory(version = i,
size = \ size = \
@ -144,6 +153,8 @@ def create_system(options, system, piobus, dma_devices):
exec("system.dir_cntrl%d = dir_cntrl" % i) exec("system.dir_cntrl%d = dir_cntrl" % i)
dir_cntrl_nodes.append(dir_cntrl) dir_cntrl_nodes.append(dir_cntrl)
cntrl_count += 1
for i, dma_device in enumerate(dma_devices): for i, dma_device in enumerate(dma_devices):
# #
# Create the Ruby objects associated with the dma controller # Create the Ruby objects associated with the dma controller
@ -153,6 +164,7 @@ def create_system(options, system, piobus, dma_devices):
physmem = system.physmem) physmem = system.physmem)
dma_cntrl = DMA_Controller(version = i, dma_cntrl = DMA_Controller(version = i,
cntrl_id = cntrl_count,
dma_sequencer = dma_seq) dma_sequencer = dma_seq)
exec("system.dma_cntrl%d = dma_cntrl" % i) 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) exec("system.dma_cntrl%d.dma_sequencer.port = dma_device.dma" % i)
dma_cntrl_nodes.append(dma_cntrl) dma_cntrl_nodes.append(dma_cntrl)
cntrl_count += 1
all_cntrls = l1_cntrl_nodes + \ all_cntrls = l1_cntrl_nodes + \
l2_cntrl_nodes + \ l2_cntrl_nodes + \
dir_cntrl_nodes + \ dir_cntrl_nodes + \

View file

@ -84,6 +84,8 @@ def create_system(options, system, piobus, dma_devices):
l2_bits = int(math.log(options.num_l2caches, 2)) l2_bits = int(math.log(options.num_l2caches, 2))
block_size_bits = int(math.log(options.cacheline_size, 2)) block_size_bits = int(math.log(options.cacheline_size, 2))
cntrl_count = 0
for i in xrange(options.num_cpus): for i in xrange(options.num_cpus):
# #
# First create the Ruby objects associated with this cpu # 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 cpu_seq.pio_port = piobus.port
l1_cntrl = L1Cache_Controller(version = i, l1_cntrl = L1Cache_Controller(version = i,
cntrl_id = cntrl_count,
sequencer = cpu_seq, sequencer = cpu_seq,
L1IcacheMemory = l1i_cache, L1IcacheMemory = l1i_cache,
L1DcacheMemory = l1d_cache, L1DcacheMemory = l1d_cache,
@ -126,6 +129,8 @@ def create_system(options, system, piobus, dma_devices):
cpu_sequencers.append(cpu_seq) cpu_sequencers.append(cpu_seq)
l1_cntrl_nodes.append(l1_cntrl) l1_cntrl_nodes.append(l1_cntrl)
cntrl_count += 1
l2_index_start = block_size_bits + l2_bits l2_index_start = block_size_bits + l2_bits
for i in xrange(options.num_l2caches): for i in xrange(options.num_l2caches):
@ -137,12 +142,15 @@ def create_system(options, system, piobus, dma_devices):
start_index_bit = l2_index_start) start_index_bit = l2_index_start)
l2_cntrl = L2Cache_Controller(version = i, l2_cntrl = L2Cache_Controller(version = i,
cntrl_id = cntrl_count,
L2cacheMemory = l2_cache, L2cacheMemory = l2_cache,
N_tokens = n_tokens) N_tokens = n_tokens)
exec("system.l2_cntrl%d = l2_cntrl" % i) exec("system.l2_cntrl%d = l2_cntrl" % i)
l2_cntrl_nodes.append(l2_cntrl) l2_cntrl_nodes.append(l2_cntrl)
cntrl_count += 1
phys_mem_size = long(system.physmem.range.second) - \ phys_mem_size = long(system.physmem.range.second) - \
long(system.physmem.range.first) + 1 long(system.physmem.range.first) + 1
mem_module_size = phys_mem_size / options.num_dirs mem_module_size = phys_mem_size / options.num_dirs
@ -158,6 +166,7 @@ def create_system(options, system, piobus, dma_devices):
dir_size.value = mem_module_size dir_size.value = mem_module_size
dir_cntrl = Directory_Controller(version = i, dir_cntrl = Directory_Controller(version = i,
cntrl_id = cntrl_count,
directory = \ directory = \
RubyDirectoryMemory(version = i, RubyDirectoryMemory(version = i,
size = \ size = \
@ -168,6 +177,8 @@ def create_system(options, system, piobus, dma_devices):
exec("system.dir_cntrl%d = dir_cntrl" % i) exec("system.dir_cntrl%d = dir_cntrl" % i)
dir_cntrl_nodes.append(dir_cntrl) dir_cntrl_nodes.append(dir_cntrl)
cntrl_count += 1
for i, dma_device in enumerate(dma_devices): for i, dma_device in enumerate(dma_devices):
# #
# Create the Ruby objects associated with the dma controller # Create the Ruby objects associated with the dma controller
@ -177,6 +188,7 @@ def create_system(options, system, piobus, dma_devices):
physmem = system.physmem) physmem = system.physmem)
dma_cntrl = DMA_Controller(version = i, dma_cntrl = DMA_Controller(version = i,
cntrl_id = cntrl_count,
dma_sequencer = dma_seq) dma_sequencer = dma_seq)
exec("system.dma_cntrl%d = dma_cntrl" % i) 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) exec("system.dma_cntrl%d.dma_sequencer.port = dma_device.dma" % i)
dma_cntrl_nodes.append(dma_cntrl) dma_cntrl_nodes.append(dma_cntrl)
cntrl_count += 1
all_cntrls = l1_cntrl_nodes + \ all_cntrls = l1_cntrl_nodes + \
l2_cntrl_nodes + \ l2_cntrl_nodes + \
dir_cntrl_nodes + \ dir_cntrl_nodes + \

View file

@ -80,6 +80,8 @@ def create_system(options, system, piobus, dma_devices):
# #
block_size_bits = int(math.log(options.cacheline_size, 2)) block_size_bits = int(math.log(options.cacheline_size, 2))
cntrl_count = 0
for i in xrange(options.num_cpus): for i in xrange(options.num_cpus):
# #
# First create the Ruby objects associated with this cpu # First create the Ruby objects associated with this cpu
@ -104,6 +106,7 @@ def create_system(options, system, piobus, dma_devices):
cpu_seq.pio_port = piobus.port cpu_seq.pio_port = piobus.port
l1_cntrl = L1Cache_Controller(version = i, l1_cntrl = L1Cache_Controller(version = i,
cntrl_id = cntrl_count,
sequencer = cpu_seq, sequencer = cpu_seq,
L1IcacheMemory = l1i_cache, L1IcacheMemory = l1i_cache,
L1DcacheMemory = l1d_cache, L1DcacheMemory = l1d_cache,
@ -121,6 +124,8 @@ def create_system(options, system, piobus, dma_devices):
cpu_sequencers.append(cpu_seq) cpu_sequencers.append(cpu_seq)
l1_cntrl_nodes.append(l1_cntrl) l1_cntrl_nodes.append(l1_cntrl)
cntrl_count += 1
phys_mem_size = long(system.physmem.range.second) - \ phys_mem_size = long(system.physmem.range.second) - \
long(system.physmem.range.first) + 1 long(system.physmem.range.first) + 1
mem_module_size = phys_mem_size / options.num_dirs 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) start_index_bit = pf_start_bit)
dir_cntrl = Directory_Controller(version = i, dir_cntrl = Directory_Controller(version = i,
cntrl_id = cntrl_count,
directory = \ directory = \
RubyDirectoryMemory( \ RubyDirectoryMemory( \
version = i, version = i,
@ -182,6 +188,8 @@ def create_system(options, system, piobus, dma_devices):
exec("system.dir_cntrl%d = dir_cntrl" % i) exec("system.dir_cntrl%d = dir_cntrl" % i)
dir_cntrl_nodes.append(dir_cntrl) dir_cntrl_nodes.append(dir_cntrl)
cntrl_count += 1
for i, dma_device in enumerate(dma_devices): for i, dma_device in enumerate(dma_devices):
# #
# Create the Ruby objects associated with the dma controller # Create the Ruby objects associated with the dma controller
@ -191,6 +199,7 @@ def create_system(options, system, piobus, dma_devices):
physmem = system.physmem) physmem = system.physmem)
dma_cntrl = DMA_Controller(version = i, dma_cntrl = DMA_Controller(version = i,
cntrl_id = cntrl_count,
dma_sequencer = dma_seq) dma_sequencer = dma_seq)
exec("system.dma_cntrl%d = dma_cntrl" % i) exec("system.dma_cntrl%d = dma_cntrl" % i)
@ -203,6 +212,8 @@ def create_system(options, system, piobus, dma_devices):
if options.recycle_latency: if options.recycle_latency:
dma_cntrl.recycle_latency = options.recycle_latency dma_cntrl.recycle_latency = options.recycle_latency
cntrl_count += 1
all_cntrls = l1_cntrl_nodes + dir_cntrl_nodes + dma_cntrl_nodes all_cntrls = l1_cntrl_nodes + dir_cntrl_nodes + dma_cntrl_nodes
return (cpu_sequencers, dir_cntrl_nodes, all_cntrls) return (cpu_sequencers, dir_cntrl_nodes, all_cntrls)

View file

@ -69,6 +69,8 @@ def create_system(options, system, piobus, dma_devices):
# controller constructors are called before the network constructor # controller constructors are called before the network constructor
# #
cntrl_count = 0
for i in xrange(options.num_cpus): for i in xrange(options.num_cpus):
# #
# First create the Ruby objects associated with this cpu # 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 cpu_seq.pio_port = piobus.port
l1_cntrl = L1Cache_Controller(version = i, l1_cntrl = L1Cache_Controller(version = i,
cntrl_id = cntrl_count,
sequencer = cpu_seq, sequencer = cpu_seq,
cacheMemory = cache) cacheMemory = cache)
@ -101,6 +104,8 @@ def create_system(options, system, piobus, dma_devices):
cpu_sequencers.append(cpu_seq) cpu_sequencers.append(cpu_seq)
l1_cntrl_nodes.append(l1_cntrl) l1_cntrl_nodes.append(l1_cntrl)
cntrl_count += 1
phys_mem_size = long(system.physmem.range.second) - \ phys_mem_size = long(system.physmem.range.second) - \
long(system.physmem.range.first) + 1 long(system.physmem.range.first) + 1
mem_module_size = phys_mem_size / options.num_dirs 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_size.value = mem_module_size
dir_cntrl = Directory_Controller(version = i, dir_cntrl = Directory_Controller(version = i,
cntrl_id = cntrl_count,
directory = \ directory = \
RubyDirectoryMemory(version = i, RubyDirectoryMemory(version = i,
size = dir_size), size = dir_size),
@ -124,6 +130,8 @@ def create_system(options, system, piobus, dma_devices):
exec("system.dir_cntrl%d = dir_cntrl" % i) exec("system.dir_cntrl%d = dir_cntrl" % i)
dir_cntrl_nodes.append(dir_cntrl) dir_cntrl_nodes.append(dir_cntrl)
cntrl_count += 1
all_cntrls = l1_cntrl_nodes + dir_cntrl_nodes all_cntrls = l1_cntrl_nodes + dir_cntrl_nodes
return (cpu_sequencers, dir_cntrl_nodes, all_cntrls) return (cpu_sequencers, dir_cntrl_nodes, all_cntrls)

View file

@ -72,24 +72,40 @@ def create_system(options, system, piobus = None, dma_devices = []):
print "Error: could not create sytem for ruby protocol %s" % protocol print "Error: could not create sytem for ruby protocol %s" % protocol
raise 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 # Important: the topology must be created before the network and after the
# controllers. # controllers.
# #
exec "import %s" % options.topology exec "import %s" % options.topology
try: try:
net_topology = eval("%s.makeTopology(all_cntrls, options)" \ net_topology = eval("%s.makeTopology(all_cntrls, options, \
IntLinkClass, ExtLinkClass, \
RouterClass)" \
% options.topology) % options.topology)
except: except:
print "Error: could not create topology %s" % options.topology print "Error: could not create topology %s" % options.topology
raise raise
if options.garnet_network == "fixed": network = NetworkClass(topology = net_topology)
network = GarnetNetwork_d(topology = net_topology)
elif options.garnet_network == "flexible":
network = GarnetNetwork(topology = net_topology)
else:
network = SimpleNetwork(topology = net_topology)
# #
# Loop through the directory controlers. # Loop through the directory controlers.

View file

@ -323,3 +323,9 @@ enumeration(RequestStatus, desc="...", default="RequestStatus_NULL") {
Aliased, desc="This request aliased with a currently outstanding request"; Aliased, desc="This request aliased with a currently outstanding request";
NULL, desc=""; NULL, desc="";
} }
// LinkDirection
enumeration(LinkDirection, desc="...") {
In, desc="Inward link direction";
Out, desc="Outward link direction";
}

View file

@ -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);
}

View file

@ -0,0 +1,96 @@
/*
* Copyright (c) 2011 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MEM_RUBY_NETWORK_BASIC_LINK_HH__
#define __MEM_RUBY_NETWORK_BASIC_LINK_HH__
#include <iostream>
#include <string>
#include <vector>
#include "params/BasicExtLink.hh"
#include "params/BasicIntLink.hh"
#include "params/BasicLink.hh"
#include "mem/ruby/network/BasicRouter.hh"
#include "mem/ruby/network/Topology.hh"
#include "mem/ruby/slicc_interface/AbstractController.hh"
#include "sim/sim_object.hh"
class BasicLink : public SimObject
{
public:
typedef BasicLinkParams Params;
BasicLink(const Params *p);
const Params *params() const { return (const Params *)_params; }
void init();
void print(std::ostream& out) const;
int m_latency;
int m_bw_multiplier;
int m_weight;
};
inline std::ostream&
operator<<(std::ostream& out, const BasicLink& obj)
{
obj.print(out);
out << std::flush;
return out;
}
class BasicExtLink : public BasicLink
{
public:
typedef BasicExtLinkParams Params;
BasicExtLink(const Params *p);
const Params *params() const { return (const Params *)_params; }
friend class Topology;
protected:
BasicRouter* m_int_node;
AbstractController* m_ext_node;
};
class BasicIntLink : public BasicLink
{
public:
typedef BasicIntLinkParams Params;
BasicIntLink(const Params *p);
const Params *params() const { return (const Params *)_params; }
friend class Topology;
protected:
BasicRouter* m_node_a;
BasicRouter* m_node_b;
};
#endif // __MEM_RUBY_NETWORK_BASIC_LINK_HH__

View file

@ -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

View file

@ -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);
}

View file

@ -0,0 +1,67 @@
/*
* Copyright (c) 2011 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MEM_RUBY_NETWORK_BASIC_ROUTER_HH__
#define __MEM_RUBY_NETWORK_BASIC_ROUTER_HH__
#include <iostream>
#include <string>
#include <vector>
#include "params/BasicRouter.hh"
#include "sim/sim_object.hh"
class BasicRouter : public SimObject
{
public:
typedef BasicRouterParams Params;
BasicRouter(const Params *p);
const Params *params() const { return (const Params *)_params; }
void init();
void print(std::ostream& out) const;
friend class Topology;
protected:
//
// ID in relation to other routers in the system
//
int m_id;
};
inline std::ostream&
operator<<(std::ostream& out, const BasicRouter& obj)
{
obj.print(out);
out << std::flush;
return out;
}
#endif // __MEM_RUBY_NETWORK_BASIC_ROUTER_HH__

View file

@ -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")

View file

@ -44,6 +44,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "mem/protocol/LinkDirection.hh"
#include "mem/protocol/MessageSizeType.hh" #include "mem/protocol/MessageSizeType.hh"
#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Global.hh"
#include "mem/ruby/system/NodeID.hh" #include "mem/ruby/system/NodeID.hh"
@ -80,15 +81,18 @@ class Network : public SimObject
virtual const std::vector<Throttle*>* getThrottles(NodeID id) const; virtual const std::vector<Throttle*>* getThrottles(NodeID id) const;
virtual int getNumNodes() {return 1;} virtual int getNumNodes() {return 1;}
virtual void makeOutLink(SwitchID src, NodeID dest, virtual void makeOutLink(SwitchID src, NodeID dest, BasicLink* link,
const NetDest& routing_table_entry, int link_latency, int link_weight, LinkDirection direction,
int bw_multiplier, bool isReconfiguration) = 0; const NetDest& routing_table_entry,
virtual void makeInLink(SwitchID src, NodeID dest, bool isReconfiguration) = 0;
const NetDest& routing_table_entry, int link_latency, virtual void makeInLink(NodeID src, SwitchID dest, BasicLink* link,
int bw_multiplier, bool isReconfiguration) = 0; LinkDirection direction,
virtual void makeInternalLink(SwitchID src, NodeID dest, const NetDest& routing_table_entry,
const NetDest& routing_table_entry, int link_latency, int link_weight, bool isReconfiguration) = 0;
int bw_multiplier, 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; virtual void reset() = 0;

View file

@ -29,32 +29,15 @@
from m5.params import * from m5.params import *
from m5.SimObject import SimObject from m5.SimObject import SimObject
from BasicLink import BasicLink
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
class Topology(SimObject): class Topology(SimObject):
type = 'Topology' type = 'Topology'
description = Param.String("Not Specified", description = Param.String("Not Specified",
"the name of the imported topology module") "the name of the imported topology module")
ext_links = VectorParam.ExtLink("Links to external nodes") ext_links = VectorParam.BasicExtLink("Links to external nodes")
int_links = VectorParam.IntLink("Links between internal nodes") int_links = VectorParam.BasicIntLink("Links between internal nodes")
num_int_nodes = Param.Int("Nunber of internal nodes") routers = VectorParam.BasicRouter("Network routers")
print_config = Param.Bool(False, print_config = Param.Bool(False,
"display topology config in the stats file") "display topology config in the stats file")

View file

@ -33,7 +33,11 @@ Import('*')
if not env['RUBY']: if not env['RUBY']:
Return() Return()
SimObject('BasicLink.py')
SimObject('BasicRouter.py')
SimObject('Network.py') SimObject('Network.py')
Source('BasicLink.cc')
Source('BasicRouter.cc')
Source('Network.cc') Source('Network.cc')
Source('Topology.cc') Source('Topology.cc')

View file

@ -33,6 +33,8 @@
#include "mem/protocol/Protocol.hh" #include "mem/protocol/Protocol.hh"
#include "mem/protocol/TopologyType.hh" #include "mem/protocol/TopologyType.hh"
#include "mem/ruby/common/NetDest.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/Network.hh"
#include "mem/ruby/network/Topology.hh" #include "mem/ruby/network/Topology.hh"
#include "mem/ruby/slicc_interface/AbstractController.hh" #include "mem/ruby/slicc_interface/AbstractController.hh"
@ -41,7 +43,8 @@
using namespace std; using namespace std;
const int INFINITE_LATENCY = 10000; // Yes, this is a big hack 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 // Note: In this file, we use the first 2*m_nodes SwitchIDs to
// represent the input and output endpoint links. These really are // represent the input and output endpoint links. These really are
@ -64,7 +67,8 @@ Topology::Topology(const Params *p)
: SimObject(p) : SimObject(p)
{ {
m_print_config = p->print_config; 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 // initialize component latencies record
m_component_latencies.resize(0); m_component_latencies.resize(0);
m_component_inter_switches.resize(0); m_component_inter_switches.resize(0);
@ -77,47 +81,68 @@ Topology::Topology(const Params *p)
if (m_nodes != params()->ext_links.size() && if (m_nodes != params()->ext_links.size() &&
m_nodes != params()->ext_links.size()) { m_nodes != params()->ext_links.size()) {
fatal("m_nodes (%d) != ext_links vector length (%d)\n", 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) // analyze both the internal and external links, create data structures
// and the network. // Note that the python created links are bi-directional, but that the
for (vector<ExtLink*>::const_iterator i = params()->ext_links.begin(); // topology and networks utilize uni-directional links. Thus each
// BasicLink is converted to two calls to add link, on for each direction
for (vector<BasicExtLink*>::const_iterator i = params()->ext_links.begin();
i != params()->ext_links.end(); ++i) { i != params()->ext_links.end(); ++i) {
const ExtLinkParams *p = (*i)->params(); BasicExtLink *ext_link = (*i);
AbstractController *c = p->ext_node; AbstractController *abs_cntrl = ext_link->params()->ext_node;
BasicRouter *router = ext_link->params()->int_node;
// Store the controller pointers for later // Store the controller and ExtLink pointers for later
m_controller_vector.push_back(c); m_controller_vector.push_back(abs_cntrl);
m_ext_link_vector.push_back(ext_link);
int ext_idx1 = int ext_idx1 = abs_cntrl->params()->cntrl_id;
MachineType_base_number(c->getMachineType()) + c->getVersion();
int ext_idx2 = ext_idx1 + m_nodes; 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 // create the internal uni-directional links in both directions
addLink(ext_idx1, int_idx, p->latency, p->bw_multiplier, p->weight); // the first direction is marked: In
addLink(int_idx, ext_idx2, p->latency, p->bw_multiplier, p->weight); addLink(ext_idx1, int_idx, ext_link, LinkDirection_In);
// the first direction is marked: Out
addLink(int_idx, ext_idx2, ext_link, LinkDirection_Out);
} }
for (vector<IntLink*>::const_iterator i = params()->int_links.begin(); for (vector<BasicIntLink*>::const_iterator i = params()->int_links.begin();
i != params()->int_links.end(); ++i) { i != params()->int_links.end(); ++i) {
const IntLinkParams *p = (*i)->params(); BasicIntLink *int_link = (*i);
int a = p->node_a + 2*m_nodes; BasicRouter *router_a = int_link->params()->node_a;
int b = p->node_b + 2*m_nodes; BasicRouter *router_b = int_link->params()->node_b;
// create the links in both directions // Store the IntLink pointers for later
addLink(a, b, p->latency, p->bw_multiplier, p->weight); m_int_link_vector.push_back(int_link);
addLink(b, a, p->latency, p->bw_multiplier, p->weight);
int a = router_a->params()->router_id + 2*m_nodes;
int b = router_b->params()->router_id + 2*m_nodes;
// create the internal uni-directional links in both directions
// the first direction is marked: In
addLink(a, b, int_link, LinkDirection_In);
// the second direction is marked: Out
addLink(b, a, int_link, LinkDirection_Out);
} }
} }
void
Topology::init()
{
}
void void
Topology::initNetworkPtr(Network* net_ptr) Topology::initNetworkPtr(Network* net_ptr)
{ {
for (int cntrl = 0; cntrl < m_controller_vector.size(); cntrl++) { for (vector<BasicExtLink*>::const_iterator i = params()->ext_links.begin();
m_controller_vector[cntrl]->initNetworkPtr(net_ptr); 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 // Find maximum switchID
SwitchID max_switch_id = 0; SwitchID max_switch_id = 0;
for (int i = 0; i < m_links_src_vector.size(); i++) { for (LinkMap::const_iterator i = m_link_map.begin();
max_switch_id = max(max_switch_id, m_links_src_vector[i]); i != m_link_map.end(); ++i) {
max_switch_id = max(max_switch_id, m_links_dest_vector[i]); std::pair<int, int> src_dest = (*i).first;
max_switch_id = max(max_switch_id, src_dest.first);
max_switch_id = max(max_switch_id, src_dest.second);
} }
// Initialize weight vector // Initialize weight, latency, and inter switched vectors
Matrix topology_weights; Matrix topology_weights;
Matrix topology_latency;
Matrix topology_bw_multis;
int num_switches = max_switch_id+1; int num_switches = max_switch_id+1;
topology_weights.resize(num_switches); 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); 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); m_component_inter_switches.resize(num_switches);
for (int i = 0; i < topology_weights.size(); i++) { for (int i = 0; i < topology_weights.size(); i++) {
topology_weights[i].resize(num_switches); 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); 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); m_component_inter_switches[i].resize(num_switches);
for (int j = 0; j < topology_weights[i].size(); j++) { for (int j = 0; j < topology_weights[i].size(); j++) {
topology_weights[i][j] = INFINITE_LATENCY; topology_weights[i][j] = INFINITE_LATENCY;
// initialize to invalid values // initialize to invalid values
topology_latency[i][j] = -1;
topology_bw_multis[i][j] = -1;
m_component_latencies[i][j] = -1; m_component_latencies[i][j] = -1;
// initially assume direct connections / no intermediate // initially assume direct connections / no intermediate
@ -175,13 +188,14 @@ Topology::createLinks(Network *net, bool isReconfiguration)
} }
// Fill in the topology weights and bandwidth multipliers // Fill in the topology weights and bandwidth multipliers
for (int i = 0; i < m_links_src_vector.size(); i++) { for (LinkMap::const_iterator i = m_link_map.begin();
int src = m_links_src_vector[i]; i != m_link_map.end(); ++i) {
int dst = m_links_dest_vector[i]; std::pair<int, int> src_dest = (*i).first;
topology_weights[src][dst] = m_links_weight_vector[i]; BasicLink* link = (*i).second.link;
topology_latency[src][dst] = m_links_latency_vector[i]; int src = src_dest.first;
m_component_latencies[src][dst] = m_links_latency_vector[i]; int dst = src_dest.second;
topology_bw_multis[src][dst] = m_bw_multiplier_vector[i]; m_component_latencies[src][dst] = link->m_latency;
topology_weights[src][dst] = link->m_weight;
} }
// Walk topology and hookup the links // Walk topology and hookup the links
@ -190,74 +204,69 @@ Topology::createLinks(Network *net, bool isReconfiguration)
for (int i = 0; i < topology_weights.size(); i++) { for (int i = 0; i < topology_weights.size(); i++) {
for (int j = 0; j < topology_weights[i].size(); j++) { for (int j = 0; j < topology_weights[i].size(); j++) {
int weight = topology_weights[i][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) { if (weight > 0 && weight != INFINITE_LATENCY) {
NetDest destination_set = shortest_path_to_node(i, j, NetDest destination_set = shortest_path_to_node(i, j,
topology_weights, dist); topology_weights, dist);
assert(latency != -1); makeLink(net, i, j, destination_set, isReconfiguration);
makeLink(net, i, j, destination_set, latency, weight,
bw_multiplier, isReconfiguration);
} }
} }
} }
} }
SwitchID
Topology::newSwitchID()
{
m_number_of_switches++;
return m_number_of_switches-1+m_nodes+m_nodes;
}
void void
Topology::addLink(SwitchID src, SwitchID dest, int link_latency) Topology::addLink(SwitchID src, SwitchID dest, BasicLink* link,
{ LinkDirection dir)
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)
{ {
assert(src <= m_number_of_switches+m_nodes+m_nodes); assert(src <= m_number_of_switches+m_nodes+m_nodes);
assert(dest <= 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); std::pair<int, int> src_dest_pair;
m_links_latency_vector.push_back(link_latency); LinkEntry link_entry;
m_links_weight_vector.push_back(link_weight);
m_bw_multiplier_vector.push_back(bw_multiplier); 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 void
Topology::makeLink(Network *net, SwitchID src, SwitchID dest, Topology::makeLink(Network *net, SwitchID src, SwitchID dest,
const NetDest& routing_table_entry, int link_latency, int link_weight, const NetDest& routing_table_entry, bool isReconfiguration)
int bw_multiplier, bool isReconfiguration)
{ {
// Make sure we're not trying to connect two end-point nodes // Make sure we're not trying to connect two end-point nodes
// directly together // directly together
assert(src >= 2 * m_nodes || dest >= 2 * m_nodes); assert(src >= 2 * m_nodes || dest >= 2 * m_nodes);
std::pair<int, int> src_dest;
LinkEntry link_entry;
if (src < m_nodes) { if (src < m_nodes) {
net->makeInLink(src, dest-(2*m_nodes), routing_table_entry, src_dest.first = src;
link_latency, bw_multiplier, isReconfiguration); 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) { } else if (dest < 2*m_nodes) {
assert(dest >= m_nodes); assert(dest >= m_nodes);
NodeID node = dest-m_nodes; NodeID node = dest - m_nodes;
net->makeOutLink(src-(2*m_nodes), node, routing_table_entry, src_dest.first = src;
link_latency, link_weight, bw_multiplier, isReconfiguration); 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 { } else {
assert((src >= 2*m_nodes) && (dest >= 2*m_nodes)); assert((src >= 2 * m_nodes) && (dest >= 2 * m_nodes));
net->makeInternalLink(src-(2*m_nodes), dest-(2*m_nodes), src_dest.first = src;
routing_table_entry, link_latency, link_weight, bw_multiplier, src_dest.second = dest;
isReconfiguration); 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); 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);
}

View file

@ -44,42 +44,24 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "mem/protocol/LinkDirection.hh"
#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Global.hh"
#include "mem/ruby/system/NodeID.hh" #include "mem/ruby/system/NodeID.hh"
#include "params/ExtLink.hh"
#include "params/IntLink.hh"
#include "params/Link.hh"
#include "params/Topology.hh" #include "params/Topology.hh"
#include "sim/sim_object.hh" #include "sim/sim_object.hh"
class Network;
class NetDest; class NetDest;
class Network;
typedef std::vector<std::vector<int> > Matrix; typedef std::vector<std::vector<int> > Matrix;
class Link : public SimObject struct LinkEntry
{ {
public: BasicLink *link;
typedef LinkParams Params; LinkDirection direction;
Link(const Params *p) : SimObject(p) {}
const Params *params() const { return (const Params *)_params; }
}; };
class ExtLink : public Link typedef std::map<std::pair<int, int>, LinkEntry> LinkMap;
{
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; }
};
class Topology : public SimObject class Topology : public SimObject
{ {
@ -89,6 +71,7 @@ class Topology : public SimObject
virtual ~Topology() {} virtual ~Topology() {}
const Params *params() const { return (const Params *)_params; } const Params *params() const { return (const Params *)_params; }
void init();
int numSwitches() const { return m_number_of_switches; } int numSwitches() const { return m_number_of_switches; }
void createLinks(Network *net, bool isReconfiguration); void createLinks(Network *net, bool isReconfiguration);
@ -101,19 +84,11 @@ class Topology : public SimObject
void print(std::ostream& out) const { out << "[Topology]"; } void print(std::ostream& out) const { out << "[Topology]"; }
protected: protected:
SwitchID newSwitchID(); void addLink(SwitchID src, SwitchID dest, BasicLink* link,
void addLink(SwitchID src, SwitchID dest, int link_latency); LinkDirection dir);
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 makeLink(Network *net, SwitchID src, SwitchID dest, void makeLink(Network *net, SwitchID src, SwitchID dest,
const NetDest& routing_table_entry, int link_latency, int weight, const NetDest& routing_table_entry,
int bw_multiplier, bool isReconfiguration); bool isReconfiguration);
//void makeSwitchesPerChip(std::vector<std::vector<SwitchID > > &nodePairs,
// std::vector<int> &latencies, std::vector<int> &bw_multis,
// int numberOfChips);
std::string getDesignStr(); std::string getDesignStr();
// Private copy constructor and assignment operator // Private copy constructor and assignment operator
@ -126,15 +101,14 @@ class Topology : public SimObject
int m_number_of_switches; int m_number_of_switches;
std::vector<AbstractController*> m_controller_vector; std::vector<AbstractController*> m_controller_vector;
std::vector<BasicExtLink*> m_ext_link_vector;
std::vector<SwitchID> m_links_src_vector; std::vector<BasicIntLink*> m_int_link_vector;
std::vector<SwitchID> m_links_dest_vector;
std::vector<int> m_links_latency_vector;
std::vector<int> m_links_weight_vector;
std::vector<int> m_bw_multiplier_vector;
Matrix m_component_latencies; Matrix m_component_latencies;
Matrix m_component_inter_switches; Matrix m_component_inter_switches;
LinkMap m_link_map;
std::vector<BasicRouter*> m_router_vector;
}; };
inline std::ostream& inline std::ostream&

View file

@ -32,13 +32,13 @@
#define __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_CREDIT_LINK_D_HH__ #define __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_CREDIT_LINK_D_HH__
#include "mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh" #include "mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh"
#include "params/CreditLink_d.hh"
class CreditLink_d : public NetworkLink_d class CreditLink_d : public NetworkLink_d
{ {
public: public:
CreditLink_d(int id, int link_latency, GarnetNetwork_d *net_ptr) typedef CreditLink_dParams Params;
: NetworkLink_d(id, link_latency, net_ptr) CreditLink_d(const Params *p) : NetworkLink_d(p) {}
{}
}; };
#endif // __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_CREDIT_LINK_D_HH__ #endif // __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_CREDIT_LINK_D_HH__

View file

@ -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);
}

View file

@ -0,0 +1,92 @@
/*
* Copyright (c) 2011 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_LINK_HH__
#define __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_LINK_HH__
#include <iostream>
#include <string>
#include <vector>
#include "mem/ruby/network/BasicLink.hh"
#include "mem/ruby/network/garnet/fixed-pipeline/CreditLink_d.hh"
#include "mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh"
#include "params/GarnetIntLink_d.hh"
#include "params/GarnetExtLink_d.hh"
class GarnetIntLink_d : public BasicLink
{
public:
typedef GarnetIntLink_dParams Params;
GarnetIntLink_d(const Params *p);
void init();
void print(std::ostream& out) const;
friend class GarnetNetwork_d;
protected:
NetworkLink_d* m_network_links[2];
CreditLink_d* m_credit_links[2];
};
inline std::ostream&
operator<<(std::ostream& out, const GarnetIntLink_d& obj)
{
obj.print(out);
out << std::flush;
return out;
}
class GarnetExtLink_d : public BasicLink
{
public:
typedef GarnetExtLink_dParams Params;
GarnetExtLink_d(const Params *p);
void init();
void print(std::ostream& out) const;
friend class GarnetNetwork_d;
protected:
NetworkLink_d* m_network_links[2];
CreditLink_d* m_credit_links[2];
};
inline std::ostream&
operator<<(std::ostream& out, const GarnetExtLink_d& obj)
{
obj.print(out);
out << std::flush;
return out;
}
#endif // __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_LINK_HH__

View file

@ -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")

View file

@ -34,7 +34,9 @@
#include "mem/protocol/MachineType.hh" #include "mem/protocol/MachineType.hh"
#include "mem/ruby/buffers/MessageBuffer.hh" #include "mem/ruby/buffers/MessageBuffer.hh"
#include "mem/ruby/common/NetDest.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/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/GarnetNetwork_d.hh"
#include "mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.hh" #include "mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.hh"
#include "mem/ruby/network/garnet/fixed-pipeline/NetworkLink_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_network_latency = 0.0;
m_queueing_latency = 0.0; m_queueing_latency = 0.0;
m_router_ptr_vector.clear(); // record the routers
for (vector<BasicRouter*>::const_iterator i =
m_topology_ptr->params()->routers.begin();
i != m_topology_ptr->params()->routers.end(); ++i) {
Router_d* router = safe_cast<Router_d*>(*i);
m_router_ptr_vector.push_back(router);
}
// Queues that are getting messages from protocol // Queues that are getting messages from protocol
m_toNetQueues.resize(m_nodes); m_toNetQueues.resize(m_nodes);
@ -87,15 +95,17 @@ GarnetNetwork_d::init()
{ {
BaseGarnetNetwork::init(); BaseGarnetNetwork::init();
// initialize the router's network pointers
for (vector<Router_d*>::const_iterator i = m_router_ptr_vector.begin();
i != m_router_ptr_vector.end(); ++i) {
Router_d* router = safe_cast<Router_d*>(*i);
router->init_net_ptr(this);
}
// The topology pointer should have already been initialized in the // The topology pointer should have already been initialized in the
// parent network constructor // parent network constructor
assert(m_topology_ptr != NULL); assert(m_topology_ptr != NULL);
int number_of_routers = m_topology_ptr->numSwitches();
for (int i=0; i<number_of_routers; i++) {
m_router_ptr_vector.push_back(new Router_d(i, this));
}
for (int i=0; i < m_nodes; i++) { for (int i=0; i < m_nodes; i++) {
NetworkInterface_d *ni = new NetworkInterface_d(i, m_virtual_networks, NetworkInterface_d *ni = new NetworkInterface_d(i, m_virtual_networks,
this); this);
@ -104,9 +114,6 @@ GarnetNetwork_d::init()
} }
// false because this isn't a reconfiguration // false because this isn't a reconfiguration
m_topology_ptr->createLinks(this, false); m_topology_ptr->createLinks(this, false);
for (int i = 0; i < m_router_ptr_vector.size(); i++) {
m_router_ptr_vector[i]->init();
}
m_vnet_type.resize(m_virtual_networks); m_vnet_type.resize(m_virtual_networks);
for (int i = 0; i < m_vnet_type.size(); i++) { for (int i = 0; i < m_vnet_type.size(); i++) {
@ -147,17 +154,19 @@ GarnetNetwork_d::reset()
*/ */
void void
GarnetNetwork_d::makeInLink(NodeID src, SwitchID dest, GarnetNetwork_d::makeInLink(NodeID src, SwitchID dest, BasicLink* link,
const NetDest& routing_table_entry, int link_latency, int bw_multiplier, LinkDirection direction,
bool isReconfiguration) const NetDest& routing_table_entry,
bool isReconfiguration)
{ {
assert(src < m_nodes); assert(src < m_nodes);
GarnetExtLink_d* garnet_link = safe_cast<GarnetExtLink_d*>(link);
if (!isReconfiguration) { if (!isReconfiguration) {
NetworkLink_d *net_link = new NetworkLink_d NetworkLink_d* net_link = garnet_link->m_network_links[direction];
(m_link_ptr_vector.size(), link_latency, this); CreditLink_d* credit_link = garnet_link->m_credit_links[direction];
CreditLink_d *credit_link = new CreditLink_d
(m_creditlink_ptr_vector.size(), link_latency, this);
m_link_ptr_vector.push_back(net_link); m_link_ptr_vector.push_back(net_link);
m_creditlink_ptr_vector.push_back(credit_link); m_creditlink_ptr_vector.push_back(credit_link);
@ -176,24 +185,27 @@ GarnetNetwork_d::makeInLink(NodeID src, SwitchID dest,
*/ */
void void
GarnetNetwork_d::makeOutLink(SwitchID src, NodeID dest, GarnetNetwork_d::makeOutLink(SwitchID src, NodeID dest, BasicLink* link,
const NetDest& routing_table_entry, int link_latency, int link_weight, LinkDirection direction,
int bw_multiplier, bool isReconfiguration) const NetDest& routing_table_entry,
bool isReconfiguration)
{ {
assert(dest < m_nodes); assert(dest < m_nodes);
assert(src < m_router_ptr_vector.size()); assert(src < m_router_ptr_vector.size());
assert(m_router_ptr_vector[src] != NULL); assert(m_router_ptr_vector[src] != NULL);
GarnetExtLink_d* garnet_link = safe_cast<GarnetExtLink_d*>(link);
if (!isReconfiguration) { if (!isReconfiguration) {
NetworkLink_d *net_link = new NetworkLink_d NetworkLink_d* net_link = garnet_link->m_network_links[direction];
(m_link_ptr_vector.size(), link_latency, this); CreditLink_d* credit_link = garnet_link->m_credit_links[direction];
CreditLink_d *credit_link = new CreditLink_d
(m_creditlink_ptr_vector.size(), link_latency, this);
m_link_ptr_vector.push_back(net_link); m_link_ptr_vector.push_back(net_link);
m_creditlink_ptr_vector.push_back(credit_link); m_creditlink_ptr_vector.push_back(credit_link);
m_router_ptr_vector[src]->addOutPort(net_link, routing_table_entry, 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); m_ni_ptr_vector[dest]->addInPort(net_link, credit_link);
} else { } else {
fatal("Fatal Error:: Reconfiguration not allowed here"); fatal("Fatal Error:: Reconfiguration not allowed here");
@ -206,21 +218,24 @@ GarnetNetwork_d::makeOutLink(SwitchID src, NodeID dest,
*/ */
void void
GarnetNetwork_d::makeInternalLink(SwitchID src, SwitchID dest, GarnetNetwork_d::makeInternalLink(SwitchID src, SwitchID dest, BasicLink* link,
const NetDest& routing_table_entry, int link_latency, int link_weight, LinkDirection direction,
int bw_multiplier, bool isReconfiguration) const NetDest& routing_table_entry,
bool isReconfiguration)
{ {
GarnetIntLink_d* garnet_link = safe_cast<GarnetIntLink_d*>(link);
if (!isReconfiguration) { if (!isReconfiguration) {
NetworkLink_d *net_link = new NetworkLink_d NetworkLink_d* net_link = garnet_link->m_network_links[direction];
(m_link_ptr_vector.size(), link_latency, this); CreditLink_d* credit_link = garnet_link->m_credit_links[direction];
CreditLink_d *credit_link = new CreditLink_d
(m_creditlink_ptr_vector.size(), link_latency, this);
m_link_ptr_vector.push_back(net_link); m_link_ptr_vector.push_back(net_link);
m_creditlink_ptr_vector.push_back(credit_link); m_creditlink_ptr_vector.push_back(credit_link);
m_router_ptr_vector[dest]->addInPort(net_link, credit_link); m_router_ptr_vector[dest]->addInPort(net_link, credit_link);
m_router_ptr_vector[src]->addOutPort(net_link, routing_table_entry, m_router_ptr_vector[src]->addOutPort(net_link, routing_table_entry,
link_weight, credit_link); link->m_weight,
credit_link);
} else { } else {
fatal("Fatal Error:: Reconfiguration not allowed here"); fatal("Fatal Error:: Reconfiguration not allowed here");
// do nothing // do nothing

View file

@ -105,15 +105,18 @@ class GarnetNetwork_d : public BaseGarnetNetwork
void reset(); void reset();
// Methods used by Topology to setup the network // Methods used by Topology to setup the network
void makeOutLink(SwitchID src, NodeID dest, void makeOutLink(SwitchID src, NodeID dest, BasicLink* link,
const NetDest& routing_table_entry, int link_latency, int link_weight, LinkDirection direction,
int bw_multiplier, bool isReconfiguration); const NetDest& routing_table_entry,
void makeInLink(SwitchID src, NodeID dest, bool isReconfiguration);
const NetDest& routing_table_entry, int link_latency, void makeInLink(NodeID src, SwitchID dest, BasicLink* link,
int bw_multiplier, bool isReconfiguration); LinkDirection direction,
void makeInternalLink(SwitchID src, NodeID dest, const NetDest& routing_table_entry,
const NetDest& routing_table_entry, int link_latency, int link_weight, bool isReconfiguration);
int bw_multiplier, bool isReconfiguration); void makeInternalLink(SwitchID src, SwitchID dest, BasicLink* link,
LinkDirection direction,
const NetDest& routing_table_entry,
bool isReconfiguration);
private: private:
void checkNetworkAllocation(NodeID id, bool ordered, int network_num); void checkNetworkAllocation(NodeID id, bool ordered, int network_num);

View file

@ -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")

View file

@ -28,22 +28,20 @@
* Authors: Niket Agarwal * 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" #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_latency = p->link_latency;
m_id = id; channel_width = p->channel_width;
m_latency = link_latency; m_id = p->link_id;
linkBuffer = new flitBuffer_d(); linkBuffer = new flitBuffer_d();
m_link_utilized = 0; m_link_utilized = 0;
m_vc_load.resize(m_net_ptr->getVCsPerClass() * m_vc_load.resize(p->vcs_per_class * p->virt_nets);
net_ptr->getNumberOfVirtualNetworks());
for (int i = 0; for (int i = 0; i < (p->vcs_per_class * p->virt_nets); i++) {
i < m_net_ptr->getVCsPerClass()*net_ptr->getNumberOfVirtualNetworks();
i++) {
m_vc_load[i] = 0; m_vc_load[i] = 0;
} }
} }
@ -89,3 +87,15 @@ NetworkLink_d::getLinkUtilization()
{ {
return m_link_utilized; return m_link_utilized;
} }
NetworkLink_d *
NetworkLink_dParams::create()
{
return new NetworkLink_d(this);
}
CreditLink_d *
CreditLink_dParams::create()
{
return new CreditLink_d(this);
}

View file

@ -38,16 +38,18 @@
#include "mem/ruby/network/garnet/fixed-pipeline/flitBuffer_d.hh" #include "mem/ruby/network/garnet/fixed-pipeline/flitBuffer_d.hh"
#include "mem/ruby/network/garnet/NetworkHeader.hh" #include "mem/ruby/network/garnet/NetworkHeader.hh"
#include "mem/ruby/network/orion/NetworkPower.hh" #include "mem/ruby/network/orion/NetworkPower.hh"
#include "params/NetworkLink_d.hh"
#include "sim/sim_object.hh"
class GarnetNetwork_d; class GarnetNetwork_d;
class NetworkLink_d : public Consumer class NetworkLink_d : public SimObject, public Consumer
{ {
public: public:
//NetworkLink_d(int id); typedef NetworkLink_dParams Params;
NetworkLink_d(const Params *p);
~NetworkLink_d(); ~NetworkLink_d();
NetworkLink_d(int id, int link_latency, GarnetNetwork_d *net_ptr);
void setLinkConsumer(Consumer *consumer); void setLinkConsumer(Consumer *consumer);
void setSourceQueue(flitBuffer_d *srcQueue); void setSourceQueue(flitBuffer_d *srcQueue);
void print(std::ostream& out) const{} void print(std::ostream& out) const{}
@ -67,8 +69,8 @@ class NetworkLink_d : public Consumer
protected: protected:
int m_id; int m_id;
int m_latency; int m_latency;
GarnetNetwork_d *m_net_ptr;
int channel_width;
flitBuffer_d *linkBuffer; flitBuffer_d *linkBuffer;
Consumer *link_consumer; Consumer *link_consumer;
flitBuffer_d *link_srcQueue; flitBuffer_d *link_srcQueue;

View file

@ -43,14 +43,13 @@
using namespace std; using namespace std;
using m5::stl_helpers::deletePointers; 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_virtual_networks = p->virt_nets;
m_network_ptr = network_ptr; m_vc_per_vnet = p->vcs_per_class;
m_virtual_networks = network_ptr->getNumberOfVirtualNetworks(); m_num_vcs = m_virtual_networks * m_vc_per_vnet;
m_vc_per_vnet = m_network_ptr->getVCsPerClass(); m_flit_width = p->flit_width;
m_num_vcs = m_virtual_networks*m_vc_per_vnet;
m_flit_width = m_network_ptr->getFlitSize();
m_routing_unit = new RoutingUnit_d(this); m_routing_unit = new RoutingUnit_d(this);
m_vc_alloc = new VCallocator_d(this); m_vc_alloc = new VCallocator_d(this);
@ -88,6 +87,8 @@ Router_d::~Router_d()
void void
Router_d::init() Router_d::init()
{ {
BasicRouter::init();
m_vc_alloc->init(); m_vc_alloc->init();
m_sw_alloc->init(); m_sw_alloc->init();
m_switch->init(); m_switch->init();
@ -178,7 +179,7 @@ Router_d::calculate_performance_numbers()
void void
Router_d::printConfig(ostream& out) Router_d::printConfig(ostream& out)
{ {
out << "[Router " << m_id << "] :: " << endl; out << name() << endl;
out << "[inLink - "; out << "[inLink - ";
for (int i = 0;i < m_input_unit.size(); i++) for (int i = 0;i < m_input_unit.size(); i++)
out << m_input_unit[i]->get_inlink_id() << " - "; 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 << m_output_unit[i]->get_outlink_id() << " - ";
out << "]" << endl; out << "]" << endl;
} }
Router_d *
GarnetRouter_dParams::create()
{
return new Router_d(this);
}

View file

@ -35,9 +35,11 @@
#include <vector> #include <vector>
#include "mem/ruby/common/NetDest.hh" #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/fixed-pipeline/flit_d.hh"
#include "mem/ruby/network/garnet/NetworkHeader.hh" #include "mem/ruby/network/garnet/NetworkHeader.hh"
#include "mem/ruby/network/orion/NetworkPower.hh" #include "mem/ruby/network/orion/NetworkPower.hh"
#include "params/GarnetRouter_d.hh"
class GarnetNetwork_d; class GarnetNetwork_d;
class NetworkLink_d; class NetworkLink_d;
@ -49,10 +51,11 @@ class VCallocator_d;
class SWallocator_d; class SWallocator_d;
class Switch_d; class Switch_d;
class Router_d class Router_d : public BasicRouter
{ {
public: public:
Router_d(int id, GarnetNetwork_d *network_ptr); typedef GarnetRouter_dParams Params;
Router_d(const Params *p);
~Router_d(); ~Router_d();
@ -68,6 +71,11 @@ class Router_d
int get_num_outports() { return m_output_unit.size(); } int get_num_outports() { return m_output_unit.size(); }
int get_id() { return m_id; } 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; } GarnetNetwork_d* get_net_ptr() { return m_network_ptr; }
std::vector<InputUnit_d *>& get_inputUnit_ref() { return m_input_unit; } std::vector<InputUnit_d *>& get_inputUnit_ref() { return m_input_unit; }
std::vector<OutputUnit_d *>& get_outputUnit_ref() { return m_output_unit; } std::vector<OutputUnit_d *>& get_outputUnit_ref() { return m_output_unit; }
@ -86,7 +94,6 @@ class Router_d
double get_static_power(){return m_power_sta;} double get_static_power(){return m_power_sta;}
private: private:
int m_id;
int m_virtual_networks, m_num_vcs, m_vc_per_vnet; int m_virtual_networks, m_num_vcs, m_vc_per_vnet;
GarnetNetwork_d *m_network_ptr; GarnetNetwork_d *m_network_ptr;
int m_flit_width; int m_flit_width;

View file

@ -33,8 +33,11 @@ Import('*')
if not env['RUBY']: if not env['RUBY']:
Return() Return()
SimObject('GarnetLink_d.py')
SimObject('GarnetNetwork_d.py') SimObject('GarnetNetwork_d.py')
SimObject('GarnetRouter_d.py')
Source('GarnetLink_d.cc')
Source('GarnetNetwork_d.cc', Werror=False) Source('GarnetNetwork_d.cc', Werror=False)
Source('InputUnit_d.cc', Werror=False) Source('InputUnit_d.cc', Werror=False)
Source('NetworkInterface_d.cc') Source('NetworkInterface_d.cc')

View file

@ -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);
}

View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2011 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MEM_RUBY_NETWORK_GARNET_FLEXIBLE_PIPELINE_LINK_HH__
#define __MEM_RUBY_NETWORK_GARNET_FLEXIBLE_PIPELINE_LINK_HH__
#include <iostream>
#include <string>
#include <vector>
#include "mem/ruby/network/BasicLink.hh"
#include "mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh"
#include "params/GarnetIntLink.hh"
#include "params/GarnetExtLink.hh"
class GarnetIntLink : public BasicLink
{
public:
typedef GarnetIntLinkParams Params;
GarnetIntLink(const Params *p);
void init();
void print(std::ostream& out) const;
friend class GarnetNetwork;
protected:
NetworkLink* m_network_links[2];
};
inline std::ostream&
operator<<(std::ostream& out, const GarnetIntLink& obj)
{
obj.print(out);
out << std::flush;
return out;
}
class GarnetExtLink : public BasicLink
{
public:
typedef GarnetExtLinkParams Params;
GarnetExtLink(const Params *p);
void init();
void print(std::ostream& out) const;
friend class GarnetNetwork;
protected:
NetworkLink* m_network_links[2];
};
inline std::ostream&
operator<<(std::ostream& out, const GarnetExtLink& obj)
{
obj.print(out);
out << std::flush;
return out;
}
#endif // __MEM_RUBY_NETWORK_GARNET_FLEXIBLE_PIPELINE_LINK_HH__

View file

@ -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")

View file

@ -34,6 +34,8 @@
#include "mem/protocol/MachineType.hh" #include "mem/protocol/MachineType.hh"
#include "mem/ruby/buffers/MessageBuffer.hh" #include "mem/ruby/buffers/MessageBuffer.hh"
#include "mem/ruby/common/NetDest.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/GarnetNetwork.hh"
#include "mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.hh" #include "mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.hh"
#include "mem/ruby/network/garnet/flexible-pipeline/NetworkLink.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_network_latency = 0.0;
m_queueing_latency = 0.0; m_queueing_latency = 0.0;
// record the routers
for (vector<BasicRouter*>::const_iterator i =
m_topology_ptr->params()->routers.begin();
i != m_topology_ptr->params()->routers.end(); ++i) {
Router* router = safe_cast<Router*>(*i);
m_router_ptr_vector.push_back(router);
}
// Allocate to and from queues // Allocate to and from queues
// Queues that are getting messages from protocol // Queues that are getting messages from protocol
@ -89,9 +99,11 @@ GarnetNetwork::init()
// Setup the network switches // Setup the network switches
assert (m_topology_ptr!=NULL); assert (m_topology_ptr!=NULL);
int number_of_routers = m_topology_ptr->numSwitches(); // initialize the router's network pointers
for (int i=0; i<number_of_routers; i++) { for (vector<Router*>::const_iterator i = m_router_ptr_vector.begin();
m_router_ptr_vector.push_back(new Router(i, this)); i != m_router_ptr_vector.end(); ++i) {
Router* router = safe_cast<Router*>(*i);
router->init_net_ptr(this);
} }
for (int i=0; i < m_nodes; i++) { for (int i=0; i < m_nodes; i++) {
@ -129,15 +141,18 @@ GarnetNetwork::reset()
} }
void void
GarnetNetwork::makeInLink(NodeID src, SwitchID dest, GarnetNetwork::makeInLink(NodeID src, SwitchID dest, BasicLink* link,
const NetDest& routing_table_entry, int link_latency, int bw_multiplier, LinkDirection direction,
bool isReconfiguration) const NetDest& routing_table_entry,
bool isReconfiguration)
{ {
assert(src < m_nodes); assert(src < m_nodes);
GarnetExtLink* garnet_link = safe_cast<GarnetExtLink*>(link);
if (!isReconfiguration) { if (!isReconfiguration) {
NetworkLink *net_link = new NetworkLink(m_link_ptr_vector.size(), NetworkLink *net_link = garnet_link->m_network_links[direction];
link_latency, this); net_link->init_net_ptr(this);
m_link_ptr_vector.push_back(net_link); m_link_ptr_vector.push_back(net_link);
m_router_ptr_vector[dest]->addInPort(net_link); m_router_ptr_vector[dest]->addInPort(net_link);
m_ni_ptr_vector[src]->addOutPort(net_link); m_ni_ptr_vector[src]->addOutPort(net_link);
@ -148,20 +163,23 @@ GarnetNetwork::makeInLink(NodeID src, SwitchID dest,
} }
void void
GarnetNetwork::makeOutLink(SwitchID src, NodeID dest, GarnetNetwork::makeOutLink(SwitchID src, NodeID dest, BasicLink* link,
const NetDest& routing_table_entry, int link_latency, int link_weight, LinkDirection direction,
int bw_multiplier, bool isReconfiguration) const NetDest& routing_table_entry,
bool isReconfiguration)
{ {
assert(dest < m_nodes); assert(dest < m_nodes);
assert(src < m_router_ptr_vector.size()); assert(src < m_router_ptr_vector.size());
assert(m_router_ptr_vector[src] != NULL); assert(m_router_ptr_vector[src] != NULL);
GarnetExtLink* garnet_link = safe_cast<GarnetExtLink*>(link);
if (!isReconfiguration) { if (!isReconfiguration) {
NetworkLink *net_link = new NetworkLink(m_link_ptr_vector.size(), NetworkLink *net_link = garnet_link->m_network_links[direction];
link_latency, this); net_link->init_net_ptr(this);
m_link_ptr_vector.push_back(net_link); m_link_ptr_vector.push_back(net_link);
m_router_ptr_vector[src]->addOutPort(net_link, routing_table_entry, m_router_ptr_vector[src]->addOutPort(net_link, routing_table_entry,
link_weight); link->m_weight);
m_ni_ptr_vector[dest]->addInPort(net_link); m_ni_ptr_vector[dest]->addInPort(net_link);
} else { } else {
fatal("Fatal Error:: Reconfiguration not allowed here"); fatal("Fatal Error:: Reconfiguration not allowed here");
@ -170,17 +188,20 @@ GarnetNetwork::makeOutLink(SwitchID src, NodeID dest,
} }
void void
GarnetNetwork::makeInternalLink(SwitchID src, SwitchID dest, GarnetNetwork::makeInternalLink(SwitchID src, SwitchID dest, BasicLink* link,
const NetDest& routing_table_entry, int link_latency, int link_weight, LinkDirection direction,
int bw_multiplier, bool isReconfiguration) const NetDest& routing_table_entry,
bool isReconfiguration)
{ {
GarnetIntLink* garnet_link = safe_cast<GarnetIntLink*>(link);
if (!isReconfiguration) { if (!isReconfiguration) {
NetworkLink *net_link = new NetworkLink(m_link_ptr_vector.size(), NetworkLink *net_link = garnet_link->m_network_links[direction];
link_latency, this); net_link->init_net_ptr(this);
m_link_ptr_vector.push_back(net_link); m_link_ptr_vector.push_back(net_link);
m_router_ptr_vector[dest]->addInPort(net_link); m_router_ptr_vector[dest]->addInPort(net_link);
m_router_ptr_vector[src]->addOutPort(net_link, routing_table_entry, m_router_ptr_vector[src]->addOutPort(net_link, routing_table_entry,
link_weight); link->m_weight);
} else { } else {
fatal("Fatal Error:: Reconfiguration not allowed here"); fatal("Fatal Error:: Reconfiguration not allowed here");
// do nothing // do nothing

View file

@ -89,15 +89,18 @@ class GarnetNetwork : public BaseGarnetNetwork
void reset(); void reset();
// Methods used by Topology to setup the network // Methods used by Topology to setup the network
void makeOutLink(SwitchID src, NodeID dest, void makeOutLink(SwitchID src, NodeID dest, BasicLink* link,
const NetDest& routing_table_entry, int link_latency, LinkDirection direction,
int link_weight, int bw_multiplier, bool isReconfiguration); const NetDest& routing_table_entry,
void makeInLink(SwitchID src, NodeID dest, bool isReconfiguration);
const NetDest& routing_table_entry, int link_latency, void makeInLink(NodeID src, SwitchID dest, BasicLink* link,
int bw_multiplier, bool isReconfiguration); LinkDirection direction,
void makeInternalLink(SwitchID src, NodeID dest, const NetDest& routing_table_entry,
const NetDest& routing_table_entry, int link_latency, bool isReconfiguration);
int link_weight, int bw_multiplier, bool isReconfiguration); void makeInternalLink(SwitchID src, SwitchID dest, BasicLink* link,
LinkDirection direction,
const NetDest& routing_table_entry,
bool isReconfiguration);
private: private:
void checkNetworkAllocation(NodeID id, bool ordered, int network_num); void checkNetworkAllocation(NodeID id, bool ordered, int network_num);
@ -105,8 +108,6 @@ class GarnetNetwork : public BaseGarnetNetwork
GarnetNetwork(const GarnetNetwork& obj); GarnetNetwork(const GarnetNetwork& obj);
GarnetNetwork& operator=(const GarnetNetwork& obj); GarnetNetwork& operator=(const GarnetNetwork& obj);
// int m_virtual_networks;
// int m_nodes;
int m_flits_received, m_flits_injected; int m_flits_received, m_flits_injected;
double m_network_latency, m_queueing_latency; double m_network_latency, m_queueing_latency;
@ -120,7 +121,6 @@ class GarnetNetwork : public BaseGarnetNetwork
std::vector<NetworkLink *> m_link_ptr_vector; // All links in network std::vector<NetworkLink *> m_link_ptr_vector; // All links in network
std::vector<NetworkInterface *> m_ni_ptr_vector; // All NI's in Network std::vector<NetworkInterface *> m_ni_ptr_vector; // All NI's in Network
// Topology* m_topology_ptr;
Time m_ruby_start; Time m_ruby_start;
}; };

View file

@ -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")

View file

@ -31,17 +31,17 @@
#include "mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.hh" #include "mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.hh"
#include "mem/ruby/network/garnet/flexible-pipeline/NetworkLink.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(); linkBuffer = new flitBuffer();
m_in_port = 0; m_in_port = 0;
m_out_port = 0; m_out_port = 0;
m_link_utilized = 0; m_link_utilized = 0;
m_net_ptr = net_ptr; m_latency = p->link_latency;
m_latency = latency; m_id = p->link_id;
int num_net = net_ptr->getNumberOfVirtualNetworks(); int num_net = p->virt_nets;
int num_vc = m_net_ptr->getVCsPerClass(); int num_vc = p->vcs_per_class;
m_vc_load.resize(num_net * num_vc); m_vc_load.resize(num_net * num_vc);
for (int i = 0; i < num_net * num_vc; i++) for (int i = 0; i < num_net * num_vc; i++)
@ -158,3 +158,9 @@ NetworkLink::consumeLink()
{ {
return linkBuffer->getTopFlit(); return linkBuffer->getTopFlit();
} }
NetworkLink *
NetworkLinkParams::create()
{
return new NetworkLink(this);
}

View file

@ -38,14 +38,16 @@
#include "mem/ruby/network/garnet/flexible-pipeline/FlexibleConsumer.hh" #include "mem/ruby/network/garnet/flexible-pipeline/FlexibleConsumer.hh"
#include "mem/ruby/network/garnet/flexible-pipeline/flitBuffer.hh" #include "mem/ruby/network/garnet/flexible-pipeline/flitBuffer.hh"
#include "mem/ruby/network/garnet/NetworkHeader.hh" #include "mem/ruby/network/garnet/NetworkHeader.hh"
#include "params/NetworkLink.hh"
#include "sim/sim_object.hh"
class GarnetNetwork; class GarnetNetwork;
class NetworkLink : public FlexibleConsumer class NetworkLink : public SimObject, public FlexibleConsumer
{ {
public: public:
NetworkLink(); typedef NetworkLinkParams Params;
NetworkLink(int id, int latency, GarnetNetwork *net_ptr); NetworkLink(const Params *p);
~NetworkLink(); ~NetworkLink();
void setLinkConsumer(FlexibleConsumer *consumer); void setLinkConsumer(FlexibleConsumer *consumer);
@ -70,6 +72,11 @@ class NetworkLink : public FlexibleConsumer
double getLinkUtilization(); double getLinkUtilization();
std::vector<int> getVcLoad(); std::vector<int> getVcLoad();
void init_net_ptr(GarnetNetwork* net_ptr)
{
m_net_ptr = net_ptr;
}
protected: protected:
int m_id, m_latency; int m_id, m_latency;
int m_in_port, m_out_port; int m_in_port, m_out_port;

View file

@ -39,15 +39,15 @@
using namespace std; using namespace std;
using m5::stl_helpers::deletePointers; using m5::stl_helpers::deletePointers;
Router::Router(int id, GarnetNetwork *network_ptr) Router::Router(const Params *p)
: BasicRouter(p)
{ {
m_id = id; m_id = p->router_id;
m_net_ptr = network_ptr; m_virtual_networks = p->virt_nets;
m_virtual_networks = m_net_ptr->getNumberOfVirtualNetworks(); m_vc_per_vnet = p->vcs_per_class;
m_vc_per_vnet = m_net_ptr->getVCsPerClass();
m_round_robin_inport = 0; m_round_robin_inport = 0;
m_round_robin_start = 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); m_vc_arbiter = new VCarbiter(this);
} }
@ -440,3 +440,9 @@ Router::print(ostream& out) const
{ {
out << "[Router]"; out << "[Router]";
} }
Router *
GarnetRouterParams::create()
{
return new Router(this);
}

View file

@ -35,6 +35,7 @@
#include <vector> #include <vector>
#include "mem/ruby/common/NetDest.hh" #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/FlexibleConsumer.hh"
#include "mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.hh" #include "mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.hh"
#include "mem/ruby/network/garnet/flexible-pipeline/InVcState.hh" #include "mem/ruby/network/garnet/flexible-pipeline/InVcState.hh"
@ -42,13 +43,15 @@
#include "mem/ruby/network/garnet/flexible-pipeline/OutVcState.hh" #include "mem/ruby/network/garnet/flexible-pipeline/OutVcState.hh"
#include "mem/ruby/network/garnet/flexible-pipeline/flitBuffer.hh" #include "mem/ruby/network/garnet/flexible-pipeline/flitBuffer.hh"
#include "mem/ruby/network/garnet/NetworkHeader.hh" #include "mem/ruby/network/garnet/NetworkHeader.hh"
#include "params/GarnetRouter.hh"
class VCarbiter; class VCarbiter;
class Router : public FlexibleConsumer class Router : public BasicRouter, public FlexibleConsumer
{ {
public: public:
Router(int id, GarnetNetwork *network_ptr); typedef GarnetRouterParams Params;
Router(const Params *p);
~Router(); ~Router();
@ -67,6 +70,11 @@ class Router : public FlexibleConsumer
void printConfig(std::ostream& out) const; void printConfig(std::ostream& out) const;
void print(std::ostream& out) const; void print(std::ostream& out) const;
void init_net_ptr(GarnetNetwork* net_ptr)
{
m_net_ptr = net_ptr;
}
private: private:
int m_id; int m_id;
int m_virtual_networks, m_num_vcs, m_vc_per_vnet; int m_virtual_networks, m_num_vcs, m_vc_per_vnet;

View file

@ -33,8 +33,11 @@ Import('*')
if not env['RUBY']: if not env['RUBY']:
Return() Return()
SimObject('GarnetLink.py')
SimObject('GarnetNetwork.py') SimObject('GarnetNetwork.py')
SimObject('GarnetRouter.py')
Source('GarnetLink.cc')
Source('GarnetNetwork.cc') Source('GarnetNetwork.cc')
Source('InVcState.cc') Source('InVcState.cc')
Source('NetworkInterface.cc') Source('NetworkInterface.cc')

View file

@ -231,7 +231,6 @@ NetworkLink_d::calculate_power()
OrionLink* orion_link_ptr; OrionLink* orion_link_ptr;
static double freq_Hz; static double freq_Hz;
double link_length; double link_length;
int channel_width;
// Initialization // Initialization
const string cfg_fn = "src/mem/ruby/network/orion/router.cfg"; const string cfg_fn = "src/mem/ruby/network/orion/router.cfg";
@ -239,17 +238,19 @@ NetworkLink_d::calculate_power()
freq_Hz = orion_cfg_ptr->get<double>("FREQUENCY"); freq_Hz = orion_cfg_ptr->get<double>("FREQUENCY");
link_length = orion_cfg_ptr->get<double>("LINK_LENGTH"); link_length = orion_cfg_ptr->get<double>("LINK_LENGTH");
channel_width = m_net_ptr->getFlitSize();
orion_link_ptr = new OrionLink( orion_link_ptr = new OrionLink(
link_length, link_length,
channel_width /* channel width */, channel_width /* channel width */,
orion_cfg_ptr); orion_cfg_ptr);
//
// Dynamic Power // NOTE! I believe this calculation will be moved to McPAT, thus this
double sim_cycles = // reference to the net_ptr can be removed
(double)(g_eventQueue_ptr->getTime() - m_net_ptr->getRubyStartTime()); //
// // 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)* double Plink_dyn = orion_link_ptr->calc_dynamic_energy(channel_width/2)*
(m_link_utilized/ sim_cycles)*freq_Hz; (m_link_utilized/ sim_cycles)*freq_Hz;

View file

@ -35,6 +35,7 @@
#include "mem/protocol/TopologyType.hh" #include "mem/protocol/TopologyType.hh"
#include "mem/ruby/buffers/MessageBuffer.hh" #include "mem/ruby/buffers/MessageBuffer.hh"
#include "mem/ruby/common/NetDest.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/SimpleNetwork.hh"
#include "mem/ruby/network/simple/Switch.hh" #include "mem/ruby/network/simple/Switch.hh"
#include "mem/ruby/network/simple/Throttle.hh" #include "mem/ruby/network/simple/Throttle.hh"
@ -133,9 +134,10 @@ SimpleNetwork::~SimpleNetwork()
// From a switch to an endpoint node // From a switch to an endpoint node
void void
SimpleNetwork::makeOutLink(SwitchID src, NodeID dest, SimpleNetwork::makeOutLink(SwitchID src, NodeID dest, BasicLink* link,
const NetDest& routing_table_entry, int link_latency, int link_weight, LinkDirection direction,
int bw_multiplier, bool isReconfiguration) const NetDest& routing_table_entry,
bool isReconfiguration)
{ {
assert(dest < m_nodes); assert(dest < m_nodes);
assert(src < m_switch_ptr_vector.size()); 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], 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]; m_endpoint_switches[dest] = m_switch_ptr_vector[src];
} }
// From an endpoint node to a switch // From an endpoint node to a switch
void void
SimpleNetwork::makeInLink(NodeID src, SwitchID dest, SimpleNetwork::makeInLink(NodeID src, SwitchID dest, BasicLink* link,
const NetDest& routing_table_entry, int link_latency, int bw_multiplier, LinkDirection direction,
bool isReconfiguration) const NetDest& routing_table_entry,
bool isReconfiguration)
{ {
assert(src < m_nodes); assert(src < m_nodes);
if (isReconfiguration) { if (isReconfiguration) {
@ -168,9 +174,10 @@ SimpleNetwork::makeInLink(NodeID src, SwitchID dest,
// From a switch to a switch // From a switch to a switch
void void
SimpleNetwork::makeInternalLink(SwitchID src, SwitchID dest, SimpleNetwork::makeInternalLink(SwitchID src, SwitchID dest, BasicLink* link,
const NetDest& routing_table_entry, int link_latency, int link_weight, LinkDirection direction,
int bw_multiplier, bool isReconfiguration) const NetDest& routing_table_entry,
bool isReconfiguration)
{ {
if (isReconfiguration) { if (isReconfiguration) {
m_switch_ptr_vector[src]->reconfigureOutPort(routing_table_entry); 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 // Connect it to the two switches
m_switch_ptr_vector[dest]->addInPort(queues); m_switch_ptr_vector[dest]->addInPort(queues);
m_switch_ptr_vector[src]->addOutPort(queues, routing_table_entry, m_switch_ptr_vector[src]->addOutPort(queues, routing_table_entry,
link_latency, bw_multiplier); link->m_latency,
link->m_bw_multiplier);
} }
void void

View file

@ -70,15 +70,18 @@ class SimpleNetwork : public Network
int getNumNodes() {return m_nodes; } int getNumNodes() {return m_nodes; }
// Methods used by Topology to setup the network // Methods used by Topology to setup the network
void makeOutLink(SwitchID src, NodeID dest, void makeOutLink(SwitchID src, NodeID dest, BasicLink* link,
const NetDest& routing_table_entry, int link_latency, int link_weight, LinkDirection direction,
int bw_multiplier, bool isReconfiguration); const NetDest& routing_table_entry,
void makeInLink(SwitchID src, NodeID dest, bool isReconfiguration);
const NetDest& routing_table_entry, int link_latency, void makeInLink(NodeID src, SwitchID dest, BasicLink* link,
int bw_multiplier, bool isReconfiguration); LinkDirection direction,
void makeInternalLink(SwitchID src, NodeID dest, const NetDest& routing_table_entry,
const NetDest& routing_table_entry, int link_latency, int link_weight, bool isReconfiguration);
int bw_multiplier, 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; void print(std::ostream& out) const;

View file

@ -32,12 +32,19 @@ from m5.objects import *
class Crossbar(Topology): class Crossbar(Topology):
description='Crossbar' description='Crossbar'
def makeTopology(nodes, options): def makeTopology(nodes, options, IntLink, ExtLink, Router):
ext_links = [ExtLink(ext_node=n, int_node=i) # 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)] for (i, n) in enumerate(nodes)]
xbar = len(nodes) # node ID for crossbar switch link_count = len(nodes)
int_links = [IntLink(node_a=i, node_b=xbar) for i in range(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, return Crossbar(ext_links=ext_links, int_links=int_links,
num_int_nodes=len(nodes)+1) routers=routers)

View file

@ -34,7 +34,7 @@ class Mesh(Topology):
# Makes a generic mesh assuming an equal number of cache and directory cntrls # 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_routers = options.num_cpus
num_rows = options.mesh_rows num_rows = options.mesh_rows
@ -46,6 +46,12 @@ def makeTopology(nodes, options):
num_columns = int(num_routers / num_rows) num_columns = int(num_routers / num_rows)
assert(num_columns * num_rows == num_routers) 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 # Add all but the remainder nodes to the list of nodes to be uniformly
# distributed across the network. # distributed across the network.
network_nodes = [] network_nodes = []
@ -61,14 +67,18 @@ def makeTopology(nodes, options):
for (i, n) in enumerate(network_nodes): for (i, n) in enumerate(network_nodes):
cntrl_level, router_id = divmod(i, num_routers) cntrl_level, router_id = divmod(i, num_routers)
assert(cntrl_level < cntrls_per_router) 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 # Connect the remainding nodes to router 0. These should only be
# DMA nodes. # DMA nodes.
for (i, node) in enumerate(remainder_nodes): for (i, node) in enumerate(remainder_nodes):
assert(node.type == 'DMA_Controller') assert(node.type == 'DMA_Controller')
assert(i < remainder) 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 # Create the mesh links. First row (east-west) links then column
# (north-south) links # (north-south) links
@ -78,18 +88,22 @@ def makeTopology(nodes, options):
if (col + 1 < num_columns): if (col + 1 < num_columns):
east_id = col + (row * num_columns) east_id = col + (row * num_columns)
west_id = (col + 1) + (row * num_columns) west_id = (col + 1) + (row * num_columns)
int_links.append(IntLink(node_a=east_id, int_links.append(IntLink(link_id=link_count,
node_b=west_id, node_a=routers[east_id],
node_b=routers[west_id],
weight=1)) weight=1))
link_count += 1
for col in xrange(num_columns): for col in xrange(num_columns):
for row in xrange(num_rows): for row in xrange(num_rows):
if (row + 1 < num_rows): if (row + 1 < num_rows):
north_id = col + (row * num_columns) north_id = col + (row * num_columns)
south_id = col + ((row + 1) * num_columns) south_id = col + ((row + 1) * num_columns)
int_links.append(IntLink(node_a=north_id, int_links.append(IntLink(link_id=link_count,
node_b=south_id, node_a=routers[north_id],
node_b=routers[south_id],
weight=2)) weight=2))
link_count += 1
return Mesh(ext_links=ext_links, return Mesh(ext_links=ext_links,
int_links=int_links, int_links=int_links,
num_int_nodes=num_routers) routers=routers)

View file

@ -37,7 +37,7 @@ class MeshDirCorners(Topology):
# configurations. The network specified is similar to GEMS old file # configurations. The network specified is similar to GEMS old file
# specified network. # specified network.
def makeTopology(nodes, options): def makeTopology(nodes, options, IntLink, ExtLink, Router):
num_routers = options.num_cpus num_routers = options.num_cpus
num_rows = options.mesh_rows num_rows = options.mesh_rows
@ -65,28 +65,39 @@ def makeTopology(nodes, options):
assert(remainder == 0) assert(remainder == 0)
assert(len(dir_nodes) == 4) 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 # Connect each cache controller to the appropriate router
ext_links = [] ext_links = []
for (i, n) in enumerate(cache_nodes): for (i, n) in enumerate(cache_nodes):
cntrl_level, router_id = divmod(i, num_routers) cntrl_level, router_id = divmod(i, num_routers)
assert(cntrl_level < caches_per_router) 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. # Connect the dir nodes to the corners.
ext_links.append(ExtLink(ext_node=dir_nodes[0], int_node=0)) ext_links.append(ExtLink(link_id=link_count, ext_node=dir_nodes[0],
ext_links.append(ExtLink(ext_node=dir_nodes[1], int_node=routers[0]))
int_node=(num_columns - 1))) link_count += 1
ext_links.append(ExtLink(link_id=link_count, ext_node=dir_nodes[1],
ext_links.append(ExtLink(ext_node=dir_nodes[2], int_node=routers[num_columns - 1]))
int_node=(num_routers - num_columns))) link_count += 1
ext_links.append(ExtLink(link_id=link_count, ext_node=dir_nodes[2],
ext_links.append(ExtLink(ext_node=dir_nodes[3], int_node=routers[num_routers - num_columns]))
int_node=(num_routers - 1))) 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. # Connect the dma nodes to router 0. These should only be DMA nodes.
for (i, node) in enumerate(dma_nodes): for (i, node) in enumerate(dma_nodes):
assert(node.type == 'DMA_Controller') 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 # Create the mesh links. First row (east-west) links then column
# (north-south) links # (north-south) links
@ -96,19 +107,24 @@ def makeTopology(nodes, options):
if (col + 1 < num_columns): if (col + 1 < num_columns):
east_id = col + (row * num_columns) east_id = col + (row * num_columns)
west_id = (col + 1) + (row * num_columns) west_id = (col + 1) + (row * num_columns)
int_links.append(IntLink(node_a=east_id, int_links.append(IntLink(link_id=link_count,
node_b=west_id, node_a=routers[east_id],
node_b=routers[west_id],
weight=1)) weight=1))
link_count += 1
for col in xrange(num_columns): for col in xrange(num_columns):
for row in xrange(num_rows): for row in xrange(num_rows):
if (row + 1 < num_rows): if (row + 1 < num_rows):
north_id = col + (row * num_columns) north_id = col + (row * num_columns)
south_id = col + ((row + 1) * num_columns) south_id = col + ((row + 1) * num_columns)
int_links.append(IntLink(node_a=north_id, int_links.append(IntLink(link_id=link_count,
node_b=south_id, node_a=routers[north_id],
node_b=routers[south_id],
weight=2)) weight=2))
link_count += 1
return MeshDirCorners(ext_links=ext_links, return MeshDirCorners(ext_links=ext_links,
int_links=int_links, int_links=int_links,
num_int_nodes=num_routers) routers=routers)

View file

@ -47,6 +47,7 @@ class AbstractController : public SimObject, public Consumer
public: public:
typedef RubyControllerParams Params; typedef RubyControllerParams Params;
AbstractController(const Params *p) : SimObject(p) {} AbstractController(const Params *p) : SimObject(p) {}
const Params *params() const { return (const Params *)_params; }
// returns the number of controllers created of the specific subtype // returns the number of controllers created of the specific subtype
// virtual int getNumberOfControllers() const = 0; // virtual int getNumberOfControllers() const = 0;

View file

@ -35,6 +35,7 @@ class RubyController(SimObject):
cxx_class = 'AbstractController' cxx_class = 'AbstractController'
abstract = True abstract = True
version = Param.Int("") version = Param.Int("")
cntrl_id = Param.Int("")
transitions_per_cycle = \ transitions_per_cycle = \
Param.Int(32, "no. of SLICC state machine 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") buffer_size = Param.Int(0, "max buffer size 0 means infinite")