예제 #1
0
def build_test_system(np):
    if buildEnv['TARGET_ISA'] == "alpha":
        test_sys = makeLinuxAlphaSystem(test_mem_mode, bm[0], options.ruby)
    elif buildEnv['TARGET_ISA'] == "mips":
        test_sys = makeLinuxMipsSystem(test_mem_mode, bm[0])
    elif buildEnv['TARGET_ISA'] == "sparc":
        test_sys = makeSparcSystem(test_mem_mode, bm[0])
    elif buildEnv['TARGET_ISA'] == "x86":
        test_sys = makeLinuxX86System(test_mem_mode, options.num_cpus, bm[0],
                                      options.ruby)
    elif buildEnv['TARGET_ISA'] == "arm":
        test_sys = makeArmSystem(test_mem_mode,
                                 options.machine_type,
                                 options.num_cpus,
                                 bm[0],
                                 options.dtb_filename,
                                 bare_metal=options.bare_metal)
        if options.enable_context_switch_stats_dump:
            test_sys.enable_context_switch_stats_dump = True
    else:
        fatal("Incapable of building %s full system!", buildEnv['TARGET_ISA'])

    # Set the cache line size for the entire system
    test_sys.cache_line_size = options.cacheline_size

    # Create a top-level voltage domain
    test_sys.voltage_domain = VoltageDomain(voltage=options.sys_voltage)

    # Create a source clock for the system and set the clock period
    test_sys.clk_domain = SrcClockDomain(
        clock=options.sys_clock, voltage_domain=test_sys.voltage_domain)

    # Create a CPU voltage domain
    test_sys.cpu_voltage_domain = VoltageDomain()

    # Create a source clock for the CPUs and set the clock period
    test_sys.cpu_clk_domain = SrcClockDomain(
        clock=options.cpu_clock, voltage_domain=test_sys.cpu_voltage_domain)

    if options.kernel is not None:
        test_sys.kernel = binary(options.kernel)

    if options.script is not None:
        test_sys.readfile = options.script

    if options.lpae:
        test_sys.have_lpae = True

    if options.virtualisation:
        test_sys.have_virtualization = True

    test_sys.init_param = options.init_param

    # For now, assign all the CPUs to the same clock domain
    test_sys.cpu = [
        TestCPUClass(clk_domain=test_sys.cpu_clk_domain, cpu_id=i)
        for i in xrange(np)
    ]

    if is_kvm_cpu(TestCPUClass) or is_kvm_cpu(FutureClass):
        test_sys.vm = KvmVM()

    if options.ruby:
        # Check for timing mode because ruby does not support atomic accesses
        if not (options.cpu_type == "detailed"
                or options.cpu_type == "timing"):
            print >> sys.stderr, "Ruby requires TimingSimpleCPU or O3CPU!!"
            sys.exit(1)

        Ruby.create_system(options, True, test_sys, test_sys.iobus,
                           test_sys._dma_ports)

        # Create a seperate clock domain for Ruby
        test_sys.ruby.clk_domain = SrcClockDomain(
            clock=options.ruby_clock, voltage_domain=test_sys.voltage_domain)

        # Connect the ruby io port to the PIO bus,
        # assuming that there is just one such port.
        test_sys.iobus.master = test_sys.ruby._io_port.slave

        if options.lcacc:
            if options.topology != "Mesh":
                fatal("Accelerators currently require a Mesh topology.")
            Lcacc.create_accelerators(options, test_sys)

        for (i, cpu) in enumerate(test_sys.cpu):
            #
            # Tie the cpu ports to the correct ruby system ports
            #
            cpu.clk_domain = test_sys.cpu_clk_domain
            cpu.createThreads()
            cpu.createInterruptController()

            cpu.icache_port = test_sys.ruby._cpu_ports[i].slave
            cpu.dcache_port = test_sys.ruby._cpu_ports[i].slave

            if buildEnv['TARGET_ISA'] == "x86":
                cpu.itb.walker.port = test_sys.ruby._cpu_ports[i].slave
                cpu.dtb.walker.port = test_sys.ruby._cpu_ports[i].slave

                cpu.interrupts.pio = test_sys.ruby._cpu_ports[i].master
                cpu.interrupts.int_master = test_sys.ruby._cpu_ports[i].slave
                cpu.interrupts.int_slave = test_sys.ruby._cpu_ports[i].master

    else:
        if options.caches or options.l2cache:
            # By default the IOCache runs at the system clock
            test_sys.iocache = IOCache(addr_ranges=test_sys.mem_ranges)
            test_sys.iocache.cpu_side = test_sys.iobus.master
            test_sys.iocache.mem_side = test_sys.membus.slave
        else:
            test_sys.iobridge = Bridge(delay='50ns',
                                       ranges=test_sys.mem_ranges)
            test_sys.iobridge.slave = test_sys.iobus.master
            test_sys.iobridge.master = test_sys.membus.slave

        # Sanity check
        if options.fastmem:
            if TestCPUClass != AtomicSimpleCPU:
                fatal("Fastmem can only be used with atomic CPU!")
            if (options.caches or options.l2cache):
                fatal("You cannot use fastmem in combination with caches!")

        for i in xrange(np):
            if options.fastmem:
                test_sys.cpu[i].fastmem = True
            if options.checker:
                test_sys.cpu[i].addCheckerCpu()
            test_sys.cpu[i].createThreads()

        CacheConfig.config_cache(options, test_sys)
        MemConfig.config_mem(options, test_sys)

    return test_sys
예제 #2
0
    drive_sys.init_param = options.init_param

    return drive_sys


# Add options
parser = optparse.OptionParser()
Options.addCommonOptions(parser)
Options.addFSOptions(parser)

# Add the ruby specific and protocol specific options
if '--ruby' in sys.argv:
    Ruby.define_options(parser)

if '--lcacc' in sys.argv:
    Lcacc.define_options(parser)

(options, args) = parser.parse_args()

if '--caches' in sys.argv:
    options.cpu_type = "timing"

if args:
    print "Error: script doesn't take any positional arguments"
    sys.exit(1)

# system under test can be any CPU
(TestCPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options)

# Match the memories with the CPUs, based on the options for the test system
TestMemClass = Simulation.setMemClass(options)
def create_system(options, full_system, system, dma_ports, ruby_system):

    if buildEnv['PROTOCOL'] != 'MESI_Two_Level_Trace':
        fatal(
            "This script requires the MESI_Two_Level_Trace protocol to be built."
        )

    ruby_system.num_simics_net_ports = options.num_networkports
    ruby_system.num_TDs = options.num_tds
    ruby_system.num_acc_instances = options.num_accinstances

    acc_type_list = options.acc_types.replace(',', ' ').split()
    type_names = [Lcacc.get(acc) for acc in acc_type_list]
    ruby_system.acc_types = ",".join(type_names)

    cpu_sequencers = []

    #
    # The ruby network creation expects the list of nodes in the system to be
    # consistent with the NetDest list.  Therefore the l1 controller nodes must be
    # listed before the directory nodes and directory nodes before dma nodes, etc.
    #
    netport_cntrl_nodes = []
    l1_cntrl_nodes = []
    l2_cntrl_nodes = []
    dir_cntrl_nodes = []
    dma_cntrl_nodes = []

    #
    # Must create the individual controllers before the network to ensure the
    # controller constructors are called before the network constructor
    #
    l2_bits = int(math.log(options.num_l2caches, 2))
    block_size_bits = int(math.log(options.cacheline_size, 2))

    assert (options.num_networkports == options.num_l2caches)
    num_l1_cntrls = ((options.num_tds + options.num_networkports - 1) /
                     options.num_networkports) * options.num_networkports
    print "num_l1_cntrls = %d" % num_l1_cntrls

    for i in xrange(options.num_networkports):
        # First create the Ruby objects associated with
        # the CPU and Accelerator signal communication
        netport_cntrl = gem5NetworkPortInterface_Controller(
            version=i,
            transitions_per_cycle=options.ports,
            ruby_system=ruby_system)

        exec("ruby_system.netport_cntrl%d = netport_cntrl" % i)
        netport_cntrl_nodes.append(netport_cntrl)
        # Connect the netport controller to the network
        netport_cntrl.messageOut = ruby_system.network.slave
        netport_cntrl.messageIn = ruby_system.network.master

    for i in xrange(num_l1_cntrls):
        #
        # First create the Ruby objects associated with this cpu
        #
        l1i_cache = L1Cache(size=options.l1i_size,
                            assoc=options.l1i_assoc,
                            start_index_bit=block_size_bits,
                            is_icache=True)
        l1d_cache = L1Cache(size=options.l1d_size,
                            assoc=options.l1d_assoc,
                            start_index_bit=block_size_bits,
                            is_icache=False)

        prefetcher = RubyPrefetcher.Prefetcher()

        l1_cntrl = L1Cache_Controller(version=i,
                                      L1Icache=l1i_cache,
                                      L1Dcache=l1d_cache,
                                      l2_select_num_bits=l2_bits,
                                      l2_select_low_bit=block_size_bits,
                                      send_evictions=send_evicts(options),
                                      prefetcher=prefetcher,
                                      ruby_system=ruby_system,
                                      clk_domain=system.cpu[0].clk_domain,
                                      transitions_per_cycle=options.ports,
                                      enable_prefetch=False)

        cpu_seq = RubySequencer(version=i,
                                icache=l1i_cache,
                                dcache=l1d_cache,
                                clk_domain=system.cpu[0].clk_domain,
                                ruby_system=ruby_system)

        l1_cntrl.sequencer = cpu_seq
        exec("ruby_system.l1_cntrl%d = l1_cntrl" % i)

        # Add controllers and sequencers to the appropriate lists
        if len(cpu_sequencers) < options.num_cpus:
            cpu_sequencers.append(cpu_seq)
        l1_cntrl_nodes.append(l1_cntrl)

        # Connect the L1 controllers and the network
        l1_cntrl.requestFromL1Cache = ruby_system.network.slave
        l1_cntrl.responseFromL1Cache = ruby_system.network.slave
        l1_cntrl.unblockFromL1Cache = ruby_system.network.slave

        l1_cntrl.requestToL1Cache = ruby_system.network.master
        l1_cntrl.responseToL1Cache = ruby_system.network.master

    l2_index_start = block_size_bits + l2_bits

    for i in xrange(options.num_l2caches):
        #
        # First create the Ruby objects associated with this cpu
        #
        l2_cache = L2Cache(size=options.l2_size,
                           assoc=options.l2_assoc,
                           start_index_bit=l2_index_start)

        l2_cntrl = L2Cache_Controller(version=i,
                                      L2cache=l2_cache,
                                      transitions_per_cycle=options.ports,
                                      ruby_system=ruby_system)

        exec("ruby_system.l2_cntrl%d = l2_cntrl" % i)
        l2_cntrl_nodes.append(l2_cntrl)

        # Connect the L2 controllers and the network
        l2_cntrl.DirRequestFromL2Cache = ruby_system.network.slave
        l2_cntrl.L1RequestFromL2Cache = ruby_system.network.slave
        l2_cntrl.responseFromL2Cache = ruby_system.network.slave

        l2_cntrl.unblockToL2Cache = ruby_system.network.master
        l2_cntrl.L1RequestToL2Cache = ruby_system.network.master
        l2_cntrl.responseToL2Cache = ruby_system.network.master

    phys_mem_size = sum(map(lambda r: r.size(), system.mem_ranges))
    assert (phys_mem_size % options.num_dirs == 0)
    mem_module_size = phys_mem_size / options.num_dirs

    # Run each of the ruby memory controllers at a ratio of the frequency of
    # the ruby system
    # clk_divider value is a fix to pass regression.
    ruby_system.memctrl_clk_domain = DerivedClockDomain(
        clk_domain=ruby_system.clk_domain, clk_divider=3)

    for i in xrange(options.num_dirs):
        dir_size = MemorySize('0B')
        dir_size.value = mem_module_size

        dir_cntrl = Directory_Controller(version=i,
                                         directory=RubyDirectoryMemory(
                                             version=i, size=dir_size),
                                         transitions_per_cycle=options.ports,
                                         ruby_system=ruby_system)

        exec("ruby_system.dir_cntrl%d = dir_cntrl" % i)
        dir_cntrl_nodes.append(dir_cntrl)

        # Connect the directory controllers and the network
        dir_cntrl.requestToDir = ruby_system.network.master
        dir_cntrl.responseToDir = ruby_system.network.master
        dir_cntrl.responseFromDir = ruby_system.network.slave

    for i, dma_port in enumerate(dma_ports):
        # Create the Ruby objects associated with the dma controller
        dma_seq = DMASequencer(version=i,
                               ruby_system=ruby_system,
                               slave=dma_port)

        dma_cntrl = DMA_Controller(version=i,
                                   dma_sequencer=dma_seq,
                                   transitions_per_cycle=options.ports,
                                   ruby_system=ruby_system)

        exec("ruby_system.dma_cntrl%d = dma_cntrl" % i)
        dma_cntrl_nodes.append(dma_cntrl)

        # Connect the dma controller to the network
        dma_cntrl.responseFromDir = ruby_system.network.master
        dma_cntrl.requestToDir = ruby_system.network.slave

    all_cntrls = netport_cntrl_nodes + \
                 l1_cntrl_nodes + \
                 l2_cntrl_nodes + \
                 dir_cntrl_nodes + \
                 dma_cntrl_nodes

    # Create the io controller and the sequencer
    if full_system:
        io_seq = DMASequencer(version=len(dma_ports), ruby_system=ruby_system)
        ruby_system._io_port = io_seq
        io_controller = DMA_Controller(version=len(dma_ports),
                                       dma_sequencer=io_seq,
                                       ruby_system=ruby_system)
        ruby_system.io_controller = io_controller

        # Connect the dma controller to the network
        io_controller.responseFromDir = ruby_system.network.master
        io_controller.requestToDir = ruby_system.network.slave

        all_cntrls = all_cntrls + [io_controller]

    topology = create_topology(all_cntrls, options)
    return (cpu_sequencers, dir_cntrl_nodes, topology)
예제 #4
0
def build_test_system(np):
    if buildEnv['TARGET_ISA'] == "alpha":
        test_sys = makeLinuxAlphaSystem(test_mem_mode, bm[0], options.ruby)
    elif buildEnv['TARGET_ISA'] == "mips":
        test_sys = makeLinuxMipsSystem(test_mem_mode, bm[0])
    elif buildEnv['TARGET_ISA'] == "sparc":
        test_sys = makeSparcSystem(test_mem_mode, bm[0])
    elif buildEnv['TARGET_ISA'] == "x86":
        test_sys = makeLinuxX86System(test_mem_mode, options.num_cpus, bm[0],
                options.ruby)
    elif buildEnv['TARGET_ISA'] == "arm":
        test_sys = makeArmSystem(test_mem_mode, options.machine_type,
                                 options.num_cpus, bm[0], options.dtb_filename,
                                 bare_metal=options.bare_metal)
        if options.enable_context_switch_stats_dump:
            test_sys.enable_context_switch_stats_dump = True
    else:
        fatal("Incapable of building %s full system!", buildEnv['TARGET_ISA'])

    # Set the cache line size for the entire system
    test_sys.cache_line_size = options.cacheline_size

    # Create a top-level voltage domain
    test_sys.voltage_domain = VoltageDomain(voltage = options.sys_voltage)

    # Create a source clock for the system and set the clock period
    test_sys.clk_domain = SrcClockDomain(clock =  options.sys_clock,
            voltage_domain = test_sys.voltage_domain)

    # Create a CPU voltage domain
    test_sys.cpu_voltage_domain = VoltageDomain()

    # Create a source clock for the CPUs and set the clock period
    test_sys.cpu_clk_domain = SrcClockDomain(clock = options.cpu_clock,
                                             voltage_domain =
                                             test_sys.cpu_voltage_domain)

    if options.kernel is not None:
        test_sys.kernel = binary(options.kernel)

    if options.script is not None:
        test_sys.readfile = options.script

    if options.lpae:
        test_sys.have_lpae = True

    if options.virtualisation:
        test_sys.have_virtualization = True

    test_sys.init_param = options.init_param

    # For now, assign all the CPUs to the same clock domain
    test_sys.cpu = [TestCPUClass(clk_domain=test_sys.cpu_clk_domain, cpu_id=i)
                    for i in xrange(np)]

    if is_kvm_cpu(TestCPUClass) or is_kvm_cpu(FutureClass):
        test_sys.vm = KvmVM()

    if options.ruby:
        # Check for timing mode because ruby does not support atomic accesses
        if not (options.cpu_type == "detailed" or options.cpu_type == "timing"):
            print >> sys.stderr, "Ruby requires TimingSimpleCPU or O3CPU!!"
            sys.exit(1)

        Ruby.create_system(options, True, test_sys, test_sys.iobus,
                           test_sys._dma_ports)

        # Create a seperate clock domain for Ruby
        test_sys.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock,
                                        voltage_domain = test_sys.voltage_domain)

        # Connect the ruby io port to the PIO bus,
        # assuming that there is just one such port.
        test_sys.iobus.master = test_sys.ruby._io_port.slave

	if options.lcacc:
    	    if options.topology != "Mesh":
                fatal("Accelerators currently require a Mesh topology.");
    	    Lcacc.create_accelerators(options, test_sys)

        for (i, cpu) in enumerate(test_sys.cpu):
            #
            # Tie the cpu ports to the correct ruby system ports
            #
            cpu.clk_domain = test_sys.cpu_clk_domain
            cpu.createThreads()
            cpu.createInterruptController()

            cpu.icache_port = test_sys.ruby._cpu_ports[i].slave
            cpu.dcache_port = test_sys.ruby._cpu_ports[i].slave

            if buildEnv['TARGET_ISA'] == "x86":
                cpu.itb.walker.port = test_sys.ruby._cpu_ports[i].slave
                cpu.dtb.walker.port = test_sys.ruby._cpu_ports[i].slave

                cpu.interrupts.pio = test_sys.ruby._cpu_ports[i].master
                cpu.interrupts.int_master = test_sys.ruby._cpu_ports[i].slave
                cpu.interrupts.int_slave = test_sys.ruby._cpu_ports[i].master

    else:
        if options.caches or options.l2cache:
            # By default the IOCache runs at the system clock
            test_sys.iocache = IOCache(addr_ranges = test_sys.mem_ranges)
            test_sys.iocache.cpu_side = test_sys.iobus.master
            test_sys.iocache.mem_side = test_sys.membus.slave
        else:
            test_sys.iobridge = Bridge(delay='50ns', ranges = test_sys.mem_ranges)
            test_sys.iobridge.slave = test_sys.iobus.master
            test_sys.iobridge.master = test_sys.membus.slave

        # Sanity check
        if options.fastmem:
            if TestCPUClass != AtomicSimpleCPU:
                fatal("Fastmem can only be used with atomic CPU!")
            if (options.caches or options.l2cache):
                fatal("You cannot use fastmem in combination with caches!")

        for i in xrange(np):
            if options.fastmem:
                test_sys.cpu[i].fastmem = True
            if options.checker:
                test_sys.cpu[i].addCheckerCpu()
            test_sys.cpu[i].createThreads()

        CacheConfig.config_cache(options, test_sys)
        MemConfig.config_mem(options, test_sys)

    return test_sys
예제 #5
0
    drive_sys.init_param = options.init_param

    return drive_sys

# Add options
parser = optparse.OptionParser()
Options.addCommonOptions(parser)
Options.addFSOptions(parser)

# Add the ruby specific and protocol specific options
if '--ruby' in sys.argv:
    Ruby.define_options(parser)

if '--lcacc' in sys.argv:
    Lcacc.define_options(parser)

(options, args) = parser.parse_args()

if '--caches' in sys.argv:
    options.cpu_type = "timing"

if args:
    print "Error: script doesn't take any positional arguments"
    sys.exit(1)

# system under test can be any CPU
(TestCPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options)

# Match the memories with the CPUs, based on the options for the test system
TestMemClass = Simulation.setMemClass(options)
def create_system(options, full_system, system, dma_ports, ruby_system):

    if buildEnv["PROTOCOL"] != "MESI_Two_Level_Trace":
        fatal("This script requires the MESI_Two_Level_Trace protocol to be built.")

    ruby_system.num_simics_net_ports = options.num_networkports
    ruby_system.num_TDs = options.num_tds
    ruby_system.num_acc_instances = options.num_accinstances

    acc_type_list = options.acc_types.replace(",", " ").split()
    type_names = [Lcacc.get(acc) for acc in acc_type_list]
    ruby_system.acc_types = ",".join(type_names)

    cpu_sequencers = []

    #
    # The ruby network creation expects the list of nodes in the system to be
    # consistent with the NetDest list.  Therefore the l1 controller nodes must be
    # listed before the directory nodes and directory nodes before dma nodes, etc.
    #
    netport_cntrl_nodes = []
    l1_cntrl_nodes = []
    l2_cntrl_nodes = []
    dir_cntrl_nodes = []
    dma_cntrl_nodes = []

    #
    # Must create the individual controllers before the network to ensure the
    # controller constructors are called before the network constructor
    #
    l2_bits = int(math.log(options.num_l2caches, 2))
    block_size_bits = int(math.log(options.cacheline_size, 2))

    assert options.num_networkports == options.num_l2caches
    num_l1_cntrls = (
        (options.num_tds + options.num_networkports - 1) / options.num_networkports
    ) * options.num_networkports
    print "num_l1_cntrls = %d" % num_l1_cntrls

    for i in xrange(options.num_networkports):
        # First create the Ruby objects associated with
        # the CPU and Accelerator signal communication
        netport_cntrl = gem5NetworkPortInterface_Controller(
            version=i, transitions_per_cycle=options.ports, ruby_system=ruby_system
        )

        exec ("ruby_system.netport_cntrl%d = netport_cntrl" % i)
        netport_cntrl_nodes.append(netport_cntrl)
        # Connect the netport controller to the network
        netport_cntrl.messageOut = ruby_system.network.slave
        netport_cntrl.messageIn = ruby_system.network.master

    for i in xrange(num_l1_cntrls):
        #
        # First create the Ruby objects associated with this cpu
        #
        l1i_cache = L1Cache(
            size=options.l1i_size, assoc=options.l1i_assoc, start_index_bit=block_size_bits, is_icache=True
        )
        l1d_cache = L1Cache(
            size=options.l1d_size, assoc=options.l1d_assoc, start_index_bit=block_size_bits, is_icache=False
        )

        prefetcher = RubyPrefetcher.Prefetcher()

        l1_cntrl = L1Cache_Controller(
            version=i,
            L1Icache=l1i_cache,
            L1Dcache=l1d_cache,
            l2_select_num_bits=l2_bits,
            l2_select_low_bit=block_size_bits,
            send_evictions=send_evicts(options),
            prefetcher=prefetcher,
            ruby_system=ruby_system,
            clk_domain=system.cpu[0].clk_domain,
            transitions_per_cycle=options.ports,
            enable_prefetch=False,
        )

        cpu_seq = RubySequencer(
            version=i, icache=l1i_cache, dcache=l1d_cache, clk_domain=system.cpu[0].clk_domain, ruby_system=ruby_system
        )

        l1_cntrl.sequencer = cpu_seq
        exec ("ruby_system.l1_cntrl%d = l1_cntrl" % i)

        # Add controllers and sequencers to the appropriate lists
        if len(cpu_sequencers) < options.num_cpus:
            cpu_sequencers.append(cpu_seq)
        l1_cntrl_nodes.append(l1_cntrl)

        # Connect the L1 controllers and the network
        l1_cntrl.requestFromL1Cache = ruby_system.network.slave
        l1_cntrl.responseFromL1Cache = ruby_system.network.slave
        l1_cntrl.unblockFromL1Cache = ruby_system.network.slave

        l1_cntrl.requestToL1Cache = ruby_system.network.master
        l1_cntrl.responseToL1Cache = ruby_system.network.master

    l2_index_start = block_size_bits + l2_bits

    for i in xrange(options.num_l2caches):
        #
        # First create the Ruby objects associated with this cpu
        #
        l2_cache = L2Cache(size=options.l2_size, assoc=options.l2_assoc, start_index_bit=l2_index_start)

        l2_cntrl = L2Cache_Controller(
            version=i, L2cache=l2_cache, transitions_per_cycle=options.ports, ruby_system=ruby_system
        )

        exec ("ruby_system.l2_cntrl%d = l2_cntrl" % i)
        l2_cntrl_nodes.append(l2_cntrl)

        # Connect the L2 controllers and the network
        l2_cntrl.DirRequestFromL2Cache = ruby_system.network.slave
        l2_cntrl.L1RequestFromL2Cache = ruby_system.network.slave
        l2_cntrl.responseFromL2Cache = ruby_system.network.slave

        l2_cntrl.unblockToL2Cache = ruby_system.network.master
        l2_cntrl.L1RequestToL2Cache = ruby_system.network.master
        l2_cntrl.responseToL2Cache = ruby_system.network.master

    phys_mem_size = sum(map(lambda r: r.size(), system.mem_ranges))
    assert phys_mem_size % options.num_dirs == 0
    mem_module_size = phys_mem_size / options.num_dirs

    # Run each of the ruby memory controllers at a ratio of the frequency of
    # the ruby system
    # clk_divider value is a fix to pass regression.
    ruby_system.memctrl_clk_domain = DerivedClockDomain(clk_domain=ruby_system.clk_domain, clk_divider=3)

    for i in xrange(options.num_dirs):
        dir_size = MemorySize("0B")
        dir_size.value = mem_module_size

        dir_cntrl = Directory_Controller(
            version=i,
            directory=RubyDirectoryMemory(version=i, size=dir_size),
            transitions_per_cycle=options.ports,
            ruby_system=ruby_system,
        )

        exec ("ruby_system.dir_cntrl%d = dir_cntrl" % i)
        dir_cntrl_nodes.append(dir_cntrl)

        # Connect the directory controllers and the network
        dir_cntrl.requestToDir = ruby_system.network.master
        dir_cntrl.responseToDir = ruby_system.network.master
        dir_cntrl.responseFromDir = ruby_system.network.slave

    for i, dma_port in enumerate(dma_ports):
        # Create the Ruby objects associated with the dma controller
        dma_seq = DMASequencer(version=i, ruby_system=ruby_system, slave=dma_port)

        dma_cntrl = DMA_Controller(
            version=i, dma_sequencer=dma_seq, transitions_per_cycle=options.ports, ruby_system=ruby_system
        )

        exec ("ruby_system.dma_cntrl%d = dma_cntrl" % i)
        dma_cntrl_nodes.append(dma_cntrl)

        # Connect the dma controller to the network
        dma_cntrl.responseFromDir = ruby_system.network.master
        dma_cntrl.requestToDir = ruby_system.network.slave

    all_cntrls = netport_cntrl_nodes + l1_cntrl_nodes + l2_cntrl_nodes + dir_cntrl_nodes + dma_cntrl_nodes

    # Create the io controller and the sequencer
    if full_system:
        io_seq = DMASequencer(version=len(dma_ports), ruby_system=ruby_system)
        ruby_system._io_port = io_seq
        io_controller = DMA_Controller(version=len(dma_ports), dma_sequencer=io_seq, ruby_system=ruby_system)
        ruby_system.io_controller = io_controller

        # Connect the dma controller to the network
        io_controller.responseFromDir = ruby_system.network.master
        io_controller.requestToDir = ruby_system.network.slave

        all_cntrls = all_cntrls + [io_controller]

    topology = create_topology(all_cntrls, options)
    return (cpu_sequencers, dir_cntrl_nodes, topology)