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