diff options
43 files changed, 636 insertions, 122 deletions
diff --git a/configs/common/CacheConfig.py b/configs/common/CacheConfig.py index 288a633ce..4b4ce7553 100644 --- a/configs/common/CacheConfig.py +++ b/configs/common/CacheConfig.py @@ -1,4 +1,4 @@ -# Copyright (c) 2012 ARM Limited +# Copyright (c) 2012-2013 ARM Limited # All rights reserved # # The license below extends only to copyright in the software and shall @@ -64,12 +64,13 @@ def config_cache(options, system): # are not connected using addTwoLevelCacheHierarchy. Use the # same clock as the CPUs, and set the L1-to-L2 bus width to 32 # bytes (256 bits). - system.l2 = l2_cache_class(clock=options.cpu_clock, + system.l2 = l2_cache_class(clk_domain=system.cpu_clk_domain, size=options.l2_size, assoc=options.l2_assoc, block_size=options.cacheline_size) - system.tol2bus = CoherentBus(clock = options.cpu_clock, width = 32) + system.tol2bus = CoherentBus(clk_domain = system.cpu_clk_domain, + width = 32) system.l2.cpu_side = system.tol2bus.master system.l2.mem_side = system.membus.slave diff --git a/configs/common/Simulation.py b/configs/common/Simulation.py index 27b1a510a..deccdad5c 100644 --- a/configs/common/Simulation.py +++ b/configs/common/Simulation.py @@ -1,4 +1,4 @@ -# Copyright (c) 2012 ARM Limited +# Copyright (c) 2012-2013 ARM Limited # All rights reserved # # The license below extends only to copyright in the software and shall @@ -308,7 +308,7 @@ def run(options, root, testsys, cpu_class): testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) switch_cpus[i].system = testsys switch_cpus[i].workload = testsys.cpu[i].workload - switch_cpus[i].clock = testsys.cpu[i].clock + switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain # simulation period if options.maxinsts: switch_cpus[i].max_insts_any_thread = options.maxinsts @@ -335,7 +335,7 @@ def run(options, root, testsys, cpu_class): for i in xrange(np): repeat_switch_cpus[i].system = testsys repeat_switch_cpus[i].workload = testsys.cpu[i].workload - repeat_switch_cpus[i].clock = testsys.cpu[i].clock + repeat_switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain if options.maxinsts: repeat_switch_cpus[i].max_insts_any_thread = options.maxinsts @@ -363,8 +363,8 @@ def run(options, root, testsys, cpu_class): switch_cpus_1[i].system = testsys switch_cpus[i].workload = testsys.cpu[i].workload switch_cpus_1[i].workload = testsys.cpu[i].workload - switch_cpus[i].clock = testsys.cpu[i].clock - switch_cpus_1[i].clock = testsys.cpu[i].clock + switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain + switch_cpus_1[i].clk_domain = testsys.cpu[i].clk_domain # if restoring, make atomic cpu simulate only a few instructions if options.checkpoint_restore != None: diff --git a/configs/example/fs.py b/configs/example/fs.py index cbcacd6d4..028148404 100644 --- a/configs/example/fs.py +++ b/configs/example/fs.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2012 ARM Limited +# Copyright (c) 2010-2013 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -81,9 +81,6 @@ def is_kvm_cpu(cpu_class): # system under test can be any CPU (TestCPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options) -TestCPUClass.clock = options.cpu_clock -DriveCPUClass.clock = options.cpu_clock - # Match the memories with the CPUs, the driver system always simple, # and based on the options for the test system DriveMemClass = SimpleMemory @@ -120,7 +117,11 @@ elif buildEnv['TARGET_ISA'] == "arm": else: fatal("Incapable of building %s full system!", buildEnv['TARGET_ISA']) -test_sys.clock = options.sys_clock +# Create a source clock for the system and set the clock period +test_sys.clk_domain = SrcClockDomain(clock = options.sys_clock) + +# Create a source clock for the CPUs and set the clock period +test_sys.cpu_clk_domain = SrcClockDomain(clock = options.cpu_clock) if options.kernel is not None: test_sys.kernel = binary(options.kernel) @@ -130,7 +131,9 @@ if options.script is not None: test_sys.init_param = options.init_param -test_sys.cpu = [TestCPUClass(cpu_id=i) for i in xrange(np)] +# 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() @@ -174,9 +177,14 @@ if len(bm) == 2: drive_sys = makeArmSystem(drive_mem_mode, options.machine_type, DriveMemClass, bm[1]) - drive_sys.clock = options.sys_clock + # Create a source clock for the system and set the clock period + drive_sys.clk_domain = SrcClockDomain(clock = options.sys_clock) + + # Create a source clock for the CPUs and set the clock period + drive_sys.cpu_clk_domain = SrcClockDomain(clock = options.cpu_clock) - drive_sys.cpu = DriveCPUClass(cpu_id=0) + drive_sys.cpu = DriveCPUClass(clk_domain=drive_sys.cpu_clk_domain, + cpu_id=0) drive_sys.cpu.createThreads() drive_sys.cpu.createInterruptController() drive_sys.cpu.connectAllPorts(drive_sys.membus) diff --git a/configs/example/memtest.py b/configs/example/memtest.py index e8dc52fb5..a74f4b2f3 100644 --- a/configs/example/memtest.py +++ b/configs/example/memtest.py @@ -144,14 +144,14 @@ for scale in treespec[:-2]: system = System(funcmem = SimpleMemory(in_addr_map = False), funcbus = NoncoherentBus(), physmem = SimpleMemory(latency = "100ns")) -system.clock = options.sys_clock +system.clk_domain = SrcClockDomain(clock = options.sys_clock) def make_level(spec, prototypes, attach_obj, attach_port): fanout = spec[0] parent = attach_obj # use attach obj as config parent too if len(spec) > 1 and (fanout > 1 or options.force_bus): port = getattr(attach_obj, attach_port) - new_bus = CoherentBus(clock="500MHz", width=16) + new_bus = CoherentBus(width=16) if (port.role == 'MASTER'): new_bus.slave = port attach_port = "master" diff --git a/configs/example/ruby_direct_test.py b/configs/example/ruby_direct_test.py index a60725230..e4d4c73f8 100644 --- a/configs/example/ruby_direct_test.py +++ b/configs/example/ruby_direct_test.py @@ -92,8 +92,9 @@ else: # actually used by the rubytester, but is included to support the # M5 memory size == Ruby memory size checks # -system = System(physmem = SimpleMemory()) -system.clock = options.sys_clock +system = System(physmem = SimpleMemory(), + clk_domain = SrcClockDomain(clock = options.sys_clock)) + # # Create the ruby random tester # @@ -103,6 +104,9 @@ system.tester = RubyDirectedTester(requests_to_complete = \ Ruby.create_system(options, system) +# Since Ruby runs at an independent frequency, create a seperate clock +system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock) + assert(options.num_cpus == len(system.ruby._cpu_ruby_ports)) for ruby_port in system.ruby._cpu_ruby_ports: diff --git a/configs/example/ruby_fs.py b/configs/example/ruby_fs.py index 403e55584..a1293a08c 100644 --- a/configs/example/ruby_fs.py +++ b/configs/example/ruby_fs.py @@ -80,8 +80,6 @@ if not (options.cpu_type == "detailed" or options.cpu_type == "timing"): sys.exit(1) (CPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options) -CPUClass.clock = options.cpu_clock - TestMemClass = Simulation.setMemClass(options) if buildEnv['TARGET_ISA'] == "alpha": @@ -93,7 +91,7 @@ elif buildEnv['TARGET_ISA'] == "x86": else: fatal("incapable of building non-alpha or non-x86 full system!") -system.clock = options.sys_clock +system.clk_domain = SrcClockDomain(clock = options.sys_clock) if options.kernel is not None: system.kernel = binary(options.kernel) @@ -102,12 +100,20 @@ if options.script is not None: system.readfile = options.script system.cpu = [CPUClass(cpu_id=i) for i in xrange(options.num_cpus)] + +# Create a source clock for the CPUs and set the clock period +system.cpu_clk_domain = SrcClockDomain(clock = options.cpu_clock) + Ruby.create_system(options, system, system.piobus, system._dma_ports) +# Create a seperate clock domain for Ruby +system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock) + for (i, cpu) in enumerate(system.cpu): # # Tie the cpu ports to the correct ruby system ports # + cpu.clk_domain = system.cpu_clk_domain cpu.createThreads() cpu.createInterruptController() cpu.icache_port = system.ruby._cpu_ruby_ports[i].slave diff --git a/configs/example/ruby_mem_test.py b/configs/example/ruby_mem_test.py index 14db9d40b..b164447f8 100644 --- a/configs/example/ruby_mem_test.py +++ b/configs/example/ruby_mem_test.py @@ -107,8 +107,8 @@ cpus = [ MemTest(atomic = False, system = System(cpu = cpus, funcmem = SimpleMemory(in_addr_map = False), funcbus = NoncoherentBus(), - physmem = SimpleMemory()) -system.clock = options.sys_clock + physmem = SimpleMemory(), + clk_domain = SrcClockDomain(clock = options.sys_clock)) if options.num_dmas > 0: dmas = [ MemTest(atomic = False, @@ -129,6 +129,9 @@ for (i, dma) in enumerate(dmas): dma_ports.append(dma.test) Ruby.create_system(options, system, dma_ports = dma_ports) +# Create a seperate clock domain for Ruby +system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock) + # # The tester is most effective when randomization is turned on and # artifical delay is randomly inserted on messages diff --git a/configs/example/ruby_network_test.py b/configs/example/ruby_network_test.py index 74bdd5504..b6fdc416f 100644 --- a/configs/example/ruby_network_test.py +++ b/configs/example/ruby_network_test.py @@ -104,11 +104,14 @@ cpus = [ NetworkTest(fixed_pkts=options.fixed_pkts, # create the desired simulated system system = System(cpu = cpus, - physmem = SimpleMemory()) -system.clock = options.sys_clock + physmem = SimpleMemory(), + clk_domain = SrcClockDomain(clock = options.sys_clock)) Ruby.create_system(options, system) +# Create a seperate clock domain for Ruby +system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock) + i = 0 for ruby_port in system.ruby._cpu_ruby_ports: # diff --git a/configs/example/ruby_random_test.py b/configs/example/ruby_random_test.py index 646863e88..cd1b82f16 100644 --- a/configs/example/ruby_random_test.py +++ b/configs/example/ruby_random_test.py @@ -97,11 +97,14 @@ tester = RubyTester(check_flush = check_flush, # actually used by the rubytester, but is included to support the # M5 memory size == Ruby memory size checks # -system = System(tester = tester, physmem = SimpleMemory()) -system.clock = options.sys_clock +system = System(tester = tester, physmem = SimpleMemory(), + clk_domain = SrcClockDomain(clock = options.sys_clock)) Ruby.create_system(options, system) +# Create a seperate clock domain for Ruby +system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock) + assert(options.num_cpus == len(system.ruby._cpu_ruby_ports)) tester.num_cpus = len(system.ruby._cpu_ruby_ports) diff --git a/configs/example/se.py b/configs/example/se.py index 3ff3f0c7d..a564901a3 100644 --- a/configs/example/se.py +++ b/configs/example/se.py @@ -1,4 +1,4 @@ -# Copyright (c) 2012 ARM Limited +# Copyright (c) 2012-2013 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -147,7 +147,6 @@ else: (CPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options) -CPUClass.clock = options.cpu_clock CPUClass.numThreads = numThreads MemClass = Simulation.setMemClass(options) @@ -159,8 +158,16 @@ if options.smt and options.num_cpus > 1: np = options.num_cpus system = System(cpu = [CPUClass(cpu_id=i) for i in xrange(np)], physmem = MemClass(range=AddrRange("512MB")), - mem_mode = test_mem_mode) -system.clock = options.sys_clock + mem_mode = test_mem_mode, + clk_domain = SrcClockDomain(clock = options.sys_clock)) + +# Create a separate clock domain for the CPUs +system.cpu_clk_domain = SrcClockDomain(clock = options.cpu_clock) + +# All cpus belong to a common cpu_clk_domain, therefore running at a common +# frequency. +for cpu in system.cpu: + cpu.clk_domain = system.cpu_clk_domain # Sanity check if options.fastmem: diff --git a/configs/ruby/MESI_CMP_directory.py b/configs/ruby/MESI_CMP_directory.py index c265bd4cb..4128f87ad 100644 --- a/configs/ruby/MESI_CMP_directory.py +++ b/configs/ruby/MESI_CMP_directory.py @@ -144,13 +144,22 @@ def create_system(options, system, piobus, dma_ports, ruby_system): system.memories.unproxy(system))) 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): # # Create the Ruby objects associated with the directory controller # - mem_cntrl = RubyMemoryControl(version = i, - ruby_system = ruby_system) + mem_cntrl = RubyMemoryControl( + clk_domain = ruby_system.memctrl_clk_domain, + version = i, + ruby_system = ruby_system) dir_size = MemorySize('0B') dir_size.value = mem_module_size diff --git a/configs/ruby/MI_example.py b/configs/ruby/MI_example.py index 0514a7240..6bbd35ea7 100644 --- a/configs/ruby/MI_example.py +++ b/configs/ruby/MI_example.py @@ -109,13 +109,22 @@ def create_system(options, system, piobus, dma_ports, ruby_system): system.memories.unproxy(system))) 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): # # Create the Ruby objects associated with the directory controller # - mem_cntrl = RubyMemoryControl(version = i, - ruby_system = ruby_system) + mem_cntrl = RubyMemoryControl( + clk_domain = ruby_system.memctrl_clk_domain, + version = i, + ruby_system = ruby_system) dir_size = MemorySize('0B') dir_size.value = mem_module_size diff --git a/configs/ruby/MOESI_CMP_directory.py b/configs/ruby/MOESI_CMP_directory.py index f53758d71..81d04914c 100644 --- a/configs/ruby/MOESI_CMP_directory.py +++ b/configs/ruby/MOESI_CMP_directory.py @@ -139,13 +139,22 @@ def create_system(options, system, piobus, dma_ports, ruby_system): system.memories.unproxy(system))) 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): # # Create the Ruby objects associated with the directory controller # - mem_cntrl = RubyMemoryControl(version = i, - ruby_system = ruby_system) + mem_cntrl = RubyMemoryControl( + clk_domain = ruby_system.memctrl_clk_domain, + version = i, + ruby_system = ruby_system) dir_size = MemorySize('0B') dir_size.value = mem_module_size diff --git a/configs/ruby/MOESI_CMP_token.py b/configs/ruby/MOESI_CMP_token.py index f3ad05a92..9c2598a1d 100644 --- a/configs/ruby/MOESI_CMP_token.py +++ b/configs/ruby/MOESI_CMP_token.py @@ -160,13 +160,22 @@ def create_system(options, system, piobus, dma_ports, ruby_system): system.memories.unproxy(system))) 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): # # Create the Ruby objects associated with the directory controller # - mem_cntrl = RubyMemoryControl(version = i, - ruby_system = ruby_system) + mem_cntrl = RubyMemoryControl( + clk_domain = ruby_system.memctrl_clk_domain, + version = i, + ruby_system = ruby_system) dir_size = MemorySize('0B') dir_size.value = mem_module_size diff --git a/configs/ruby/MOESI_hammer.py b/configs/ruby/MOESI_hammer.py index 30fb0f0b7..11ea579ea 100644 --- a/configs/ruby/MOESI_hammer.py +++ b/configs/ruby/MOESI_hammer.py @@ -158,13 +158,22 @@ def create_system(options, system, piobus, dma_ports, ruby_system): else: pf_start_bit = block_size_bits + # 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): # # Create the Ruby objects associated with the directory controller # - mem_cntrl = RubyMemoryControl(version = i, - ruby_system = ruby_system) + mem_cntrl = RubyMemoryControl( + clk_domain = ruby_system.memctrl_clk_domain, + version = i, + ruby_system = ruby_system) dir_size = MemorySize('0B') dir_size.value = mem_module_size diff --git a/configs/ruby/Network_test.py b/configs/ruby/Network_test.py index c1a1f9509..c4df4dddb 100644 --- a/configs/ruby/Network_test.py +++ b/configs/ruby/Network_test.py @@ -107,13 +107,22 @@ def create_system(options, system, piobus, dma_ports, ruby_system): system.memories.unproxy(system))) 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): # # Create the Ruby objects associated with the directory controller # - mem_cntrl = RubyMemoryControl(version = i, - ruby_system = ruby_system) + mem_cntrl = RubyMemoryControl( + clk_domain = ruby_system.memctrl_clk_domain, + version = i, + ruby_system = ruby_system) dir_size = MemorySize('0B') dir_size.value = mem_module_size diff --git a/configs/ruby/Ruby.py b/configs/ruby/Ruby.py index 5c5e84197..a35ef4f09 100644 --- a/configs/ruby/Ruby.py +++ b/configs/ruby/Ruby.py @@ -95,8 +95,7 @@ def create_topology(controllers, options): def create_system(options, system, piobus = None, dma_ports = []): - system.ruby = RubySystem(clock = options.ruby_clock, - stats_filename = options.ruby_stats, + system.ruby = RubySystem(stats_filename = options.ruby_stats, no_mem_vec = options.use_map) ruby = system.ruby diff --git a/src/arch/alpha/AlphaSystem.py b/src/arch/alpha/AlphaSystem.py index 2486ec059..cc8e453b1 100644 --- a/src/arch/alpha/AlphaSystem.py +++ b/src/arch/alpha/AlphaSystem.py @@ -45,7 +45,7 @@ class LinuxAlphaSystem(AlphaSystem): system_type = 34 system_rev = 1 << 10 - boot_cpu_frequency = Param.Frequency(Self.cpu[0].clock.frequency, + boot_cpu_frequency = Param.Frequency(Self.cpu[0].clk_domain.clock.frequency, "boot processor frequency") class FreebsdAlphaSystem(AlphaSystem): diff --git a/src/arch/mips/MipsSystem.py b/src/arch/mips/MipsSystem.py index c6ceb71db..4605b21a7 100644 --- a/src/arch/mips/MipsSystem.py +++ b/src/arch/mips/MipsSystem.py @@ -50,7 +50,7 @@ class LinuxMipsSystem(MipsSystem): system_type = 34 system_rev = 1 << 10 - boot_cpu_frequency = Param.Frequency(Self.cpu[0].clock.frequency, + boot_cpu_frequency = Param.Frequency(Self.cpu[0].clk_domain.clock.frequency, "boot processor frequency") class BareIronMipsSystem(MipsSystem): diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py index e7613c5bb..7ec79ad0a 100644 --- a/src/cpu/BaseCPU.py +++ b/src/cpu/BaseCPU.py @@ -52,6 +52,7 @@ from InstTracer import InstTracer from ExeTracer import ExeTracer from MemObject import MemObject from BranchPredictor import BranchPredictor +from ClockDomain import * default_tracer = ExeTracer() @@ -226,7 +227,10 @@ class BaseCPU(MemObject): elif buildEnv['TARGET_ISA'] == 'alpha': self.interrupts = AlphaInterrupts() elif buildEnv['TARGET_ISA'] == 'x86': - self.interrupts = X86LocalApic(clock = Parent.clock * 16, + self.apic_clk_domain = DerivedClockDomain(clk_domain = + Parent.clk_domain, + clk_divider = 16) + self.interrupts = X86LocalApic(clk_domain = self.apic_clk_domain, pio_addr=0x2000000000000000) _localApic = self.interrupts elif buildEnv['TARGET_ISA'] == 'mips': diff --git a/src/cpu/dummy_checker.cc b/src/cpu/dummy_checker.cc index 7a5b46e43..bbd905492 100644 --- a/src/cpu/dummy_checker.cc +++ b/src/cpu/dummy_checker.cc @@ -54,7 +54,7 @@ DummyCheckerParams::create() params->max_insts_all_threads = 0; params->max_loads_any_thread = 0; params->max_loads_all_threads = 0; - params->clock = clock; + params->clk_domain = clk_domain; // Hack to touch all parameters. Consider not deriving Checker // from BaseCPU..it's not really a CPU in the end. Counter temp; diff --git a/src/cpu/o3/checker.cc b/src/cpu/o3/checker.cc index 3ff3d86bc..ce7a99f0f 100644 --- a/src/cpu/o3/checker.cc +++ b/src/cpu/o3/checker.cc @@ -66,7 +66,7 @@ O3CheckerParams::create() params->exitOnError = exitOnError; params->updateOnError = updateOnError; params->warnOnlyOnLoadError = warnOnlyOnLoadError; - params->clock = clock; + params->clk_domain = clk_domain; params->tracer = tracer; // Hack to touch all parameters. Consider not deriving Checker // from BaseCPU..it's not really a CPU in the end. diff --git a/src/dev/Ethernet.py b/src/dev/Ethernet.py index 0072b90fa..147ad156c 100644 --- a/src/dev/Ethernet.py +++ b/src/dev/Ethernet.py @@ -84,8 +84,6 @@ class IGbE(EtherDevice): "Number of enteries in the rx descriptor cache") tx_desc_cache_size = Param.Int(64, "Number of enteries in the rx descriptor cache") - # Override the default clock - clock = '500MHz' VendorID = 0x8086 SubsystemID = 0x1008 SubsystemVendorID = 0x8086 @@ -135,9 +133,6 @@ class EtherDevBase(EtherDevice): hardware_address = Param.EthernetAddr(NextEthernetAddr, "Ethernet Hardware Address") - # Override the default clock - clock = '500MHz' - dma_read_delay = Param.Latency('0us', "fixed delay for dma reads") dma_read_factor = Param.Latency('0us', "multiplier for dma reads") dma_write_delay = Param.Latency('0us', "fixed delay for dma writes") diff --git a/src/mem/ruby/system/RubyMemoryControl.py b/src/mem/ruby/system/RubyMemoryControl.py index e46b3f223..118e4f20e 100644 --- a/src/mem/ruby/system/RubyMemoryControl.py +++ b/src/mem/ruby/system/RubyMemoryControl.py @@ -37,8 +37,6 @@ class RubyMemoryControl(MemoryControl): cxx_header = "mem/ruby/system/RubyMemoryControl.hh" version = Param.Int(""); - # Override the default clock - clock = '400MHz' banks_per_rank = Param.Int(8, ""); ranks_per_dimm = Param.Int(2, ""); dimms_per_channel = Param.Int(2, ""); diff --git a/src/sim/ClockDomain.py b/src/sim/ClockDomain.py new file mode 100644 index 000000000..37958dc26 --- /dev/null +++ b/src/sim/ClockDomain.py @@ -0,0 +1,60 @@ +# Copyright (c) 2013 ARM Limited +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# +# 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: Vasileios Spiliopoulos +# Akash Bagdia + +from m5.params import * +from m5.SimObject import SimObject + +# Abstract clock domain +class ClockDomain(SimObject): + type = 'ClockDomain' + cxx_header = "sim/clock_domain.hh" + abstract = True + +# Source clock domain with an actual clock +class SrcClockDomain(ClockDomain): + type = 'SrcClockDomain' + cxx_header = "sim/clock_domain.hh" + clock = Param.Clock("Clock period") + +# Derived clock domain with a parent clock domain and a frequency +# divider +class DerivedClockDomain(ClockDomain): + type = 'DerivedClockDomain' + cxx_header = "sim/clock_domain.hh" + clk_domain = Param.ClockDomain("Parent clock domain") + clk_divider = Param.Unsigned(1, "Frequency divider") diff --git a/src/sim/ClockedObject.py b/src/sim/ClockedObject.py index 8bc4031a4..2562f1f01 100644 --- a/src/sim/ClockedObject.py +++ b/src/sim/ClockedObject.py @@ -44,7 +44,6 @@ class ClockedObject(SimObject): abstract = True cxx_header = "sim/clocked_object.hh" - # Clock period of this object, with the default value being the - # clock period of the parent object, unproxied at instantiation - # time - clock = Param.Clock(Parent.clock, "Clock speed") + # The clock domain this clocked object belongs to, inheriting the + # parent's clock domain by default + clk_domain = Param.ClockDomain(Parent.clk_domain, "Clock domain") diff --git a/src/sim/SConscript b/src/sim/SConscript index 093130f24..7aa4702cd 100644 --- a/src/sim/SConscript +++ b/src/sim/SConscript @@ -34,6 +34,7 @@ SimObject('BaseTLB.py') SimObject('ClockedObject.py') SimObject('Root.py') SimObject('InstTracer.py') +SimObject('ClockDomain.py') Source('arguments.cc') Source('async.cc') @@ -50,6 +51,7 @@ Source('sim_object.cc') Source('simulate.cc') Source('stat_control.cc') Source('syscall_emul.cc') +Source('clock_domain.cc') if env['TARGET_ISA'] != 'no': SimObject('Process.py') @@ -81,3 +83,4 @@ DebugFlag('Thread') DebugFlag('Timer') DebugFlag('VtoPhys') DebugFlag('WorkItems') +DebugFlag('ClockDomain') diff --git a/src/sim/clock_domain.cc b/src/sim/clock_domain.cc new file mode 100644 index 000000000..262ae904c --- /dev/null +++ b/src/sim/clock_domain.cc @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * 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: Vasileios Spiliopoulos + * Akash Bagdia + * Andreas Hansson + */ + +#include "debug/ClockDomain.hh" +#include "params/ClockDomain.hh" +#include "params/DerivedClockDomain.hh" +#include "params/SrcClockDomain.hh" +#include "sim/clock_domain.hh" + +SrcClockDomain::SrcClockDomain(const Params *p) : ClockDomain(p) +{ + clockPeriod(p->clock); +} + +void +SrcClockDomain::clockPeriod(Tick clock_period) +{ + if (clock_period == 0) { + fatal("%s has a clock period of zero\n", name()); + } + + _clockPeriod = clock_period; + + DPRINTF(ClockDomain, + "Setting clock period to %d ticks for source clock %s\n", + _clockPeriod, name()); + + // inform any derived clocks they need to updated their period + for (auto c = children.begin(); c != children.end(); ++c) { + (*c)->updateClockPeriod(); + } +} + +SrcClockDomain * +SrcClockDomainParams::create() +{ + return new SrcClockDomain(this); +} + +DerivedClockDomain::DerivedClockDomain(const Params *p) : + ClockDomain(p), + parent(*p->clk_domain), + clockDivider(p->clk_divider) +{ + // Ensure that clock divider setting works as frequency divider and never + // work as frequency multiplier + if (clockDivider < 1) { + fatal("Clock divider param cannot be less than 1"); + } + + // let the parent keep track of this derived domain so that it can + // propagate changes + parent.addDerivedDomain(this); + + // update our clock period based on the parents clock + updateClockPeriod(); +} + +void +DerivedClockDomain::updateClockPeriod() +{ + // recalculate the clock period, relying on the fact that changes + // propagate downwards in the tree + _clockPeriod = parent.clockPeriod() * clockDivider; + + DPRINTF(ClockDomain, + "Setting clock period to %d ticks for derived clock %s\n", + _clockPeriod, name()); + + // inform any derived clocks + for (auto c = children.begin(); c != children.end(); ++c) { + (*c)->updateClockPeriod(); + } +} + +DerivedClockDomain * +DerivedClockDomainParams::create() +{ + return new DerivedClockDomain(this); +} diff --git a/src/sim/clock_domain.hh b/src/sim/clock_domain.hh new file mode 100644 index 000000000..c3f53e675 --- /dev/null +++ b/src/sim/clock_domain.hh @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2013 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * 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: Vasileios Spiliopoulos + * Akash Bagdia + */ + +/** + * @file + * ClockDomain declarations. + */ + +#ifndef __SIM_CLOCK_DOMAIN_HH__ +#define __SIM_CLOCK_DOMAIN_HH__ + +#include "base/statistics.hh" +#include "params/ClockDomain.hh" +#include "params/DerivedClockDomain.hh" +#include "params/SrcClockDomain.hh" +#include "sim/sim_object.hh" + +/** + * Forward declaration + */ +class DerivedClockDomain; + +/** + * The ClockDomain provides clock to group of clocked objects bundled + * under the same clock domain. The clock domains provide support for + * a hierarchial structure with source and derived domains. + */ +class ClockDomain : public SimObject +{ + + protected: + + /** + * Pre-computed clock period in ticks. This is populated by the + * inheriting classes based on how their period is determined. + */ + Tick _clockPeriod; + + /** + * Pointers to potential derived clock domains so we can propagate + * changes. + */ + std::vector<DerivedClockDomain*> children; + + public: + + typedef ClockDomainParams Params; + ClockDomain(const Params *p) : SimObject(p), _clockPeriod(0) {} + + /** + * Get the clock period. + * + * @return Clock period in ticks + */ + inline Tick clockPeriod() const { return _clockPeriod; } + + /** + * Add a derived domain. + * + * @param Derived domain to add as a child + */ + void addDerivedDomain(DerivedClockDomain *clock_domain) + { children.push_back(clock_domain); } + +}; + +/** + * The source clock domains provides the notion of a clock domain that is + * connected to a tunable clock source. It maintains the clock period and + * provides methods for setting/getting the clock. + */ +class SrcClockDomain : public ClockDomain +{ + + public: + + typedef SrcClockDomainParams Params; + SrcClockDomain(const Params *p); + + /** + * Set new clock value + * @param clock The new clock period in ticks + */ + void clockPeriod(Tick clock_period); + +}; + +/** + * The derived clock domains provides the notion of a clock domain + * that is connected to a parent clock domain that can either be a + * source clock domain or a derived clock domain. It maintains the + * clock divider and provides methods for getting the clock. + */ +class DerivedClockDomain: public ClockDomain +{ + + public: + + typedef DerivedClockDomainParams Params; + DerivedClockDomain(const Params *p); + + /** + * Called by the parent clock domain to propagate changes. This + * also involves propagating the change further to any children of + * the derived domain itself. + */ + void updateClockPeriod(); + + private: + + /** + * Reference to the parent clock domain this clock domain derives + * its clock period from + */ + ClockDomain &parent; + + /** + * Local clock divider of the domain + */ + const uint64_t clockDivider; +}; + +#endif diff --git a/src/sim/clocked_object.hh b/src/sim/clocked_object.hh index d836c48cc..c959c5c04 100644 --- a/src/sim/clocked_object.hh +++ b/src/sim/clocked_object.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 ARM Limited + * Copyright (c) 2012-2013 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -49,6 +49,7 @@ #include "base/misc.hh" #include "params/ClockedObject.hh" #include "sim/core.hh" +#include "sim/clock_domain.hh" #include "sim/sim_object.hh" /** @@ -88,7 +89,7 @@ class ClockedObject : public SimObject // optimise for the common case and see if the tick should be // advanced by a single clock period - tick += clock; + tick += clockPeriod(); ++cycle; // see if we are done at this point @@ -98,26 +99,25 @@ class ClockedObject : public SimObject // if not, we have to recalculate the cycle and tick, we // perform the calculations in terms of relative cycles to // allow changes to the clock period in the future - Cycles elapsedCycles(divCeil(curTick() - tick, clock)); + Cycles elapsedCycles(divCeil(curTick() - tick, clockPeriod())); cycle += elapsedCycles; - tick += elapsedCycles * clock; + tick += elapsedCycles * clockPeriod(); } - // Clock period in ticks - Tick clock; + /** + * The clock domain this clocked object belongs to + */ + ClockDomain &clockDomain; protected: /** - * Create a clocked object and set the clock based on the + * Create a clocked object and set the clock domain based on the * parameters. */ ClockedObject(const ClockedObjectParams* p) : - SimObject(p), tick(0), cycle(0), clock(p->clock) + SimObject(p), tick(0), cycle(0), clockDomain(*p->clk_domain) { - if (clock == 0) { - fatal("%s has a clock period of zero\n", name()); - } } /** @@ -132,9 +132,9 @@ class ClockedObject : public SimObject */ void resetClock() const { - Cycles elapsedCycles(divCeil(curTick(), clock)); + Cycles elapsedCycles(divCeil(curTick(), clockPeriod())); cycle = elapsedCycles; - tick = elapsedCycles * clock; + tick = elapsedCycles * clockPeriod(); } public: @@ -154,7 +154,7 @@ class ClockedObject : public SimObject update(); // figure out when this future cycle is - return tick + clock * cycles; + return tick + clockPeriod() * cycles; } /** @@ -181,12 +181,18 @@ class ClockedObject : public SimObject Tick nextCycle() const { return clockEdge(Cycles(1)); } - inline uint64_t frequency() const { return SimClock::Frequency / clock; } + inline uint64_t frequency() const + { + return SimClock::Frequency / clockPeriod(); + } - inline Tick clockPeriod() const { return clock; } + inline Tick clockPeriod() const + { + return clockDomain.clockPeriod(); + } inline Cycles ticksToCycles(Tick t) const - { return Cycles(t / clock); } + { return Cycles(t / clockPeriod()); } }; diff --git a/tests/configs/base_config.py b/tests/configs/base_config.py index 0cafacdda..16620c4dd 100644 --- a/tests/configs/base_config.py +++ b/tests/configs/base_config.py @@ -74,9 +74,10 @@ class BaseSystem(object): self.num_cpus = num_cpus self.checker = checker - def create_cpus(self): + def create_cpus(self, cpu_clk_domain): """Return a list of CPU objects to add to a system.""" - cpus = [ self.cpu_class(cpu_id=i, clock='2GHz') + cpus = [ self.cpu_class(clk_domain = cpu_clk_domain, + cpu_id=i) for i in range(self.num_cpus) ] if self.checker: for c in cpus: @@ -101,8 +102,9 @@ class BaseSystem(object): Returns: A bus that CPUs should use to connect to the shared cache. """ - system.toL2Bus = CoherentBus(clock='2GHz') - system.l2c = L2Cache(clock='2GHz', size='4MB', assoc=8) + system.toL2Bus = CoherentBus(clk_domain=system.cpu_clk_domain) + system.l2c = L2Cache(clk_domain=system.cpu_clk_domain, + size='4MB', assoc=8) system.l2c.cpu_side = system.toL2Bus.master system.l2c.mem_side = system.membus.slave return system.toL2Bus @@ -134,8 +136,8 @@ class BaseSystem(object): Arguments: system -- System to initialize. """ - system.clock = '1GHz' - system.cpu = self.create_cpus() + self.create_clk_src(system) + system.cpu = self.create_cpus(system.cpu_clk_domain) if _have_kvm_support and \ any([isinstance(c, BaseKvmCPU) for c in system.cpu]): @@ -145,6 +147,16 @@ class BaseSystem(object): for cpu in system.cpu: self.init_cpu(system, cpu, sha_bus) + def create_clk_src(self,system): + # Create system clock domain. This provides clock value to every + # clocked object that lies beneath it unless explicitly overwritten + # by a different clock domain. + system.clk_domain = SrcClockDomain(clock = '1GHz') + + # Create a seperate clock domain for components that should + # run at CPUs frequency + system.cpu_clk_domain = SrcClockDomain(clock = '2GHz') + @abstractmethod def create_system(self): """Create an return an initialized system.""" @@ -244,8 +256,10 @@ class BaseFSSwitcheroo(BaseFSSystem): BaseFSSystem.__init__(self, **kwargs) self.cpu_classes = tuple(cpu_classes) - def create_cpus(self): - cpus = [ cclass(cpu_id=0, clock='2GHz', switched_out=True) + def create_cpus(self, cpu_clk_domain): + cpus = [ cclass(clk_domain = cpu_clk_domain, + cpu_id=0, + switched_out=True) for cclass in self.cpu_classes ] cpus[0].switched_out = False return cpus diff --git a/tests/configs/memtest-ruby.py b/tests/configs/memtest-ruby.py index dbd1082d1..3261ba3ff 100644 --- a/tests/configs/memtest-ruby.py +++ b/tests/configs/memtest-ruby.py @@ -69,7 +69,7 @@ options.l3_assoc=2 nb_cores = 8 # ruby does not support atomic, functional, or uncacheable accesses -cpus = [ MemTest(clock = '2GHz', atomic=False, percent_functional=50, +cpus = [ MemTest(atomic=False, percent_functional=50, percent_uncacheable=0, suppress_func_warnings=True) \ for i in xrange(nb_cores) ] @@ -80,11 +80,22 @@ options.num_cpus = nb_cores system = System(cpu = cpus, funcmem = SimpleMemory(in_addr_map = False), physmem = SimpleMemory(null = True), - funcbus = NoncoherentBus()) -system.clock = options.sys_clock + funcbus = NoncoherentBus(), + clk_domain = SrcClockDomain(clock = options.sys_clock)) + +# Create a seperate clock domain for components that should run at +# CPUs frequency +system.cpu_clk_domain = SrcClockDomain(clock = '2GHz') + +# All cpus are associated with cpu_clk_domain +for cpu in cpus: + cpu.clk_domain = system.cpu_clk_domain Ruby.create_system(options, system) +# Create a separate clock domain for Ruby +system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock) + assert(len(cpus) == len(system.ruby._cpu_ruby_ports)) for (i, ruby_port) in enumerate(system.ruby._cpu_ruby_ports): diff --git a/tests/configs/memtest.py b/tests/configs/memtest.py index efaae6133..35efe646d 100644 --- a/tests/configs/memtest.py +++ b/tests/configs/memtest.py @@ -33,18 +33,21 @@ from Caches import * #MAX CORES IS 8 with the fals sharing method nb_cores = 8 -cpus = [ MemTest(clock = '2GHz') for i in xrange(nb_cores) ] +cpus = [ MemTest() for i in xrange(nb_cores) ] # system simulated system = System(cpu = cpus, funcmem = SimpleMemory(in_addr_map = False), funcbus = NoncoherentBus(), physmem = SimpleMemory(), - membus = CoherentBus(width=16)) -system.clock = '1GHz' + membus = CoherentBus(width=16), + clk_domain = SrcClockDomain(clock = '1GHz')) -# l2cache & bus -system.toL2Bus = CoherentBus(clock="2GHz", width=16) -system.l2c = L2Cache(clock = '2GHz', size='64kB', assoc=8) +# Create a seperate clock domain for components that should run at +# CPUs frequency +system.cpu_clk_domain = SrcClockDomain(clock = '2GHz') + +system.toL2Bus = CoherentBus(clk_domain = system.cpu_clk_domain, width=16) +system.l2c = L2Cache(clk_domain = system.cpu_clk_domain, size='64kB', assoc=8) system.l2c.cpu_side = system.toL2Bus.master # connect l2c to membus @@ -52,6 +55,8 @@ system.l2c.mem_side = system.membus.slave # add L1 caches for cpu in cpus: + # All cpus are associated with cpu_clk_domain + cpu.clk_domain = system.cpu_clk_domain cpu.l1c = L1Cache(size = '32kB', assoc = 4) cpu.l1c.cpu_side = cpu.test cpu.l1c.mem_side = system.toL2Bus.slave diff --git a/tests/configs/o3-timing-mp-ruby.py b/tests/configs/o3-timing-mp-ruby.py index 0060689b8..292c7a42d 100644 --- a/tests/configs/o3-timing-mp-ruby.py +++ b/tests/configs/o3-timing-mp-ruby.py @@ -39,14 +39,19 @@ ruby_memory = ruby_config.generate("TwoLevel_SplitL1UnifiedL2.rb", nb_cores) # system simulated system = System(cpu = cpus, physmem = ruby_memory, membus = CoherentBus(), - mem_mode = "timing") -system.clock = '1GHz' + mem_mode = "timing", + clk_domain = SrcClockDomain(clock = '1GHz')) + +# Create a seperate clock domain for components that should run at +# CPUs frequency +system.cpu_clk_domain = SrcClockDomain(clock = '2GHz') for cpu in cpus: # create the interrupt controller cpu.createInterruptController() cpu.connectAllPorts(system.membus) - cpu.clock = '2GHz' + # All cpus are associated with cpu_clk_domain + cpu.clk_domain = system.cpu_clk_domain # connect memory to membus system.physmem.port = system.membus.master diff --git a/tests/configs/o3-timing-ruby.py b/tests/configs/o3-timing-ruby.py index 22e1047a3..d1b471bac 100644 --- a/tests/configs/o3-timing-ruby.py +++ b/tests/configs/o3-timing-ruby.py @@ -36,13 +36,17 @@ import ruby_config ruby_memory = ruby_config.generate("TwoLevel_SplitL1UnifiedL2.rb", 1) cpu = DerivO3CPU(cpu_id=0) -cpu.clock = '2GHz' system = System(cpu = cpu, physmem = ruby_memory, membus = CoherentBus(), - mem_mode = "timing") -system.clock = '1GHz' + mem_mode = "timing", + clk_domain = SrcClockDomain(clock = '1GHz')) + +# Create a seperate clock domain for components that should run at +# CPUs frequency +system.cpu.clk_domain = SrcClockDomain(clock = '2GHz') + system.physmem.port = system.membus.master # create the interrupt controller cpu.createInterruptController() diff --git a/tests/configs/pc-simple-timing-ruby.py b/tests/configs/pc-simple-timing-ruby.py index f17083fe4..5799c0c7a 100644 --- a/tests/configs/pc-simple-timing-ruby.py +++ b/tests/configs/pc-simple-timing-ruby.py @@ -56,11 +56,16 @@ options.num_cpus = 2 #the system mdesc = SysConfig(disk = 'linux-x86.img') system = FSConfig.makeLinuxX86System('timing', DDR3_1600_x64, options.num_cpus, - mdesc=mdesc, Ruby=True) + mdesc=mdesc, Ruby=True, + system.kernel = FSConfig.binary('x86_64-vmlinux-2.6.22.9.smp') system.cpu = [TimingSimpleCPU(cpu_id=i) for i in xrange(options.num_cpus)] + Ruby.create_system(options, system, system.piobus, system._dma_ports) +# Create a seperate clock domain for Ruby +system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock) + for (i, cpu) in enumerate(system.cpu): # create the interrupt controller cpu.createInterruptController() @@ -72,7 +77,6 @@ for (i, cpu) in enumerate(system.cpu): cpu.interrupts.pio = system.piobus.master cpu.interrupts.int_master = system.piobus.slave cpu.interrupts.int_slave = system.piobus.master - cpu.clock = '2GHz' # Set access_phys_mem to True for ruby port system.ruby._cpu_ruby_ports[i].access_phys_mem = True diff --git a/tests/configs/rubytest-ruby.py b/tests/configs/rubytest-ruby.py index 328337190..1553e29f4 100644 --- a/tests/configs/rubytest-ruby.py +++ b/tests/configs/rubytest-ruby.py @@ -77,11 +77,14 @@ if buildEnv['PROTOCOL'] == 'MOESI_hammer': tester = RubyTester(check_flush = check_flush, checks_to_complete = 100, wakeup_frequency = 10, num_cpus = options.num_cpus) -system = System(tester = tester, physmem = SimpleMemory(null = True)) -system.clock = options.sys_clock +system = System(tester = tester, physmem = SimpleMemory(null = True), + clk_domain = SrcClockDomain(clock = options.sys_clock)) Ruby.create_system(options, system) +# Create a separate clock domain for Ruby +system.ruby.clk_domain = SrcClockDomain(clock = '1GHz') + assert(options.num_cpus == len(system.ruby._cpu_ruby_ports)) # diff --git a/tests/configs/simple-atomic-mp-ruby.py b/tests/configs/simple-atomic-mp-ruby.py index 12c26d97b..9feccb12c 100644 --- a/tests/configs/simple-atomic-mp-ruby.py +++ b/tests/configs/simple-atomic-mp-ruby.py @@ -38,13 +38,18 @@ import ruby_config ruby_memory = ruby_config.generate("TwoLevel_SplitL1UnifiedL2.rb", nb_cores) # system simulated -system = System(cpu = cpus, physmem = ruby_memory, membus = CoherentBus()) -system.clock = '1GHz' +system = System(cpu = cpus, physmem = ruby_memory, membus = CoherentBus(), + clk_domain = SrcClockDomain(clock = '1GHz')) + +# Create a seperate clock domain for components that should run at +# CPUs frequency +system.cpu.clk_domain = SrcClockDomain(clock = '2GHz') # add L1 caches for cpu in cpus: cpu.connectAllPorts(system.membus) - cpu.clock = '2GHz' + # All cpus are associated with cpu_clk_domain + cpu.clk_domain = system.cpu_clk_domain # connect memory to membus system.physmem.port = system.membus.master diff --git a/tests/configs/simple-timing-mp-ruby.py b/tests/configs/simple-timing-mp-ruby.py index 2fa314d09..835428c3b 100644 --- a/tests/configs/simple-timing-mp-ruby.py +++ b/tests/configs/simple-timing-mp-ruby.py @@ -71,11 +71,18 @@ cpus = [ TimingSimpleCPU(cpu_id=i) for i in xrange(nb_cores) ] options.num_cpus = nb_cores # system simulated -system = System(cpu = cpus, physmem = SimpleMemory()) -system.clock = options.sys_clock +system = System(cpu = cpus, physmem = SimpleMemory(), + clk_domain = SrcClockDomain(clock = '1GHz')) + +# Create a seperate clock domain for components that should run at +# CPUs frequency +system.cpu.clk_domain = SrcClockDomain(clock = '2GHz') Ruby.create_system(options, system) +# Create a separate clock domain for Ruby +system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock) + assert(options.num_cpus == len(system.ruby._cpu_ruby_ports)) for (i, cpu) in enumerate(system.cpu): diff --git a/tests/configs/simple-timing-ruby.py b/tests/configs/simple-timing-ruby.py index 9057475a5..27d56a31d 100644 --- a/tests/configs/simple-timing-ruby.py +++ b/tests/configs/simple-timing-ruby.py @@ -67,11 +67,18 @@ options.l3_assoc=2 options.num_cpus = 1 cpu = TimingSimpleCPU(cpu_id=0) -system = System(cpu = cpu, physmem = SimpleMemory(null = True)) -system.clock = options.sys_clock +system = System(cpu = cpu, physmem = SimpleMemory(null = True), + clk_domain = SrcClockDomain(clock = '1GHz')) + +# Create a seperate clock domain for components that should run at +# CPUs frequency +system.cpu.clk_domain = SrcClockDomain(clock = '2GHz') Ruby.create_system(options, system) +# Create a separate clock for Ruby +system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock) + assert(len(system.ruby._cpu_ruby_ports) == 1) # create the interrupt controller diff --git a/tests/configs/tgen-simple-dram.py b/tests/configs/tgen-simple-dram.py index a79b65d43..394aac4cb 100644 --- a/tests/configs/tgen-simple-dram.py +++ b/tests/configs/tgen-simple-dram.py @@ -49,8 +49,8 @@ cpu = TrafficGen(config_file = "tests/quick/se/70.tgen/tgen-simple-dram.cfg") # system simulated system = System(cpu = cpu, physmem = DDR3_1600_x64(), - membus = NoncoherentBus(width = 16)) -system.clock = '1GHz' + membus = NoncoherentBus(width = 16), + clk_domain = SrcClockDomain(clock = '1GHz')) # add a communication monitor system.monitor = CommMonitor() diff --git a/tests/configs/tgen-simple-mem.py b/tests/configs/tgen-simple-mem.py index b93165f50..2d39a2ab0 100644 --- a/tests/configs/tgen-simple-mem.py +++ b/tests/configs/tgen-simple-mem.py @@ -49,8 +49,8 @@ cpu = TrafficGen(config_file = "tests/quick/se/70.tgen/tgen-simple-mem.cfg") # system simulated system = System(cpu = cpu, physmem = SimpleMemory(), - membus = NoncoherentBus(width = 16)) -system.clock = '1GHz' + membus = NoncoherentBus(width = 16), + clk_domain = SrcClockDomain(clock = '1GHz')) # add a communication monitor, and also trace all the packets system.monitor = CommMonitor(trace_file = "monitor.ptrc.gz") diff --git a/tests/configs/twosys-tsunami-simple-atomic.py b/tests/configs/twosys-tsunami-simple-atomic.py index 8025b4e7b..22c6686ae 100644 --- a/tests/configs/twosys-tsunami-simple-atomic.py +++ b/tests/configs/twosys-tsunami-simple-atomic.py @@ -34,12 +34,22 @@ from Benchmarks import * test_sys = makeLinuxAlphaSystem('atomic', SimpleMemory, SysConfig('netperf-stream-client.rcS')) -test_sys.clock = '1GHz' + +# Create the system clock domain +test_sys.clk_domain = SrcClockDomain(clock = '1GHz') + test_sys.cpu = AtomicSimpleCPU(cpu_id=0) # create the interrupt controller test_sys.cpu.createInterruptController() test_sys.cpu.connectAllPorts(test_sys.membus) -test_sys.cpu.clock = '2GHz' + +# Create a seperate clock domain for components that should run at +# CPUs frequency +test_sys.cpu.clk_domain = SrcClockDomain(clock = '2GHz') + +# Create a separate clock domain for Ethernet +test_sys.tsunami.ethernet.clk_domain = SrcClockDomain(clock = '500MHz') + # In contrast to the other (one-system) Tsunami configurations we do # not have an IO cache but instead rely on an IO bridge for accesses # from masters on the IO bus to the memory bus @@ -49,12 +59,20 @@ test_sys.iobridge.master = test_sys.membus.slave drive_sys = makeLinuxAlphaSystem('atomic', SimpleMemory, SysConfig('netperf-server.rcS')) -drive_sys.clock = '1GHz' +# Create the system clock domain +drive_sys.clk_domain = SrcClockDomain(clock = '1GHz') drive_sys.cpu = AtomicSimpleCPU(cpu_id=0) # create the interrupt controller drive_sys.cpu.createInterruptController() drive_sys.cpu.connectAllPorts(drive_sys.membus) -drive_sys.cpu.clock = '4GHz' + +# Create a seperate clock domain for components that should run at +# CPUs frequency +drive_sys.cpu.clk_domain = SrcClockDomain(clock = '4GHz') + +# Create a separate clock domain for Ethernet +drive_sys.tsunami.ethernet.clk_domain = SrcClockDomain(clock = '500MHz') + drive_sys.iobridge = Bridge(delay='50ns', ranges = drive_sys.mem_ranges) drive_sys.iobridge.slave = drive_sys.iobus.master drive_sys.iobridge.master = drive_sys.membus.slave |