summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configs/common/CacheConfig.py7
-rw-r--r--configs/common/Simulation.py10
-rw-r--r--configs/example/fs.py24
-rw-r--r--configs/example/memtest.py4
-rw-r--r--configs/example/ruby_direct_test.py8
-rw-r--r--configs/example/ruby_fs.py12
-rw-r--r--configs/example/ruby_mem_test.py7
-rw-r--r--configs/example/ruby_network_test.py7
-rw-r--r--configs/example/ruby_random_test.py7
-rw-r--r--configs/example/se.py15
-rw-r--r--configs/ruby/MESI_CMP_directory.py13
-rw-r--r--configs/ruby/MI_example.py13
-rw-r--r--configs/ruby/MOESI_CMP_directory.py13
-rw-r--r--configs/ruby/MOESI_CMP_token.py13
-rw-r--r--configs/ruby/MOESI_hammer.py13
-rw-r--r--configs/ruby/Network_test.py13
-rw-r--r--configs/ruby/Ruby.py3
-rw-r--r--src/arch/alpha/AlphaSystem.py2
-rw-r--r--src/arch/mips/MipsSystem.py2
-rw-r--r--src/cpu/BaseCPU.py6
-rw-r--r--src/cpu/dummy_checker.cc2
-rw-r--r--src/cpu/o3/checker.cc2
-rw-r--r--src/dev/Ethernet.py5
-rw-r--r--src/mem/ruby/system/RubyMemoryControl.py2
-rw-r--r--src/sim/ClockDomain.py60
-rw-r--r--src/sim/ClockedObject.py7
-rw-r--r--src/sim/SConscript3
-rw-r--r--src/sim/clock_domain.cc118
-rw-r--r--src/sim/clock_domain.hh160
-rw-r--r--src/sim/clocked_object.hh40
-rw-r--r--tests/configs/base_config.py30
-rw-r--r--tests/configs/memtest-ruby.py17
-rw-r--r--tests/configs/memtest.py17
-rw-r--r--tests/configs/o3-timing-mp-ruby.py11
-rw-r--r--tests/configs/o3-timing-ruby.py10
-rw-r--r--tests/configs/pc-simple-timing-ruby.py8
-rw-r--r--tests/configs/rubytest-ruby.py7
-rw-r--r--tests/configs/simple-atomic-mp-ruby.py11
-rw-r--r--tests/configs/simple-timing-mp-ruby.py11
-rw-r--r--tests/configs/simple-timing-ruby.py11
-rw-r--r--tests/configs/tgen-simple-dram.py4
-rw-r--r--tests/configs/tgen-simple-mem.py4
-rw-r--r--tests/configs/twosys-tsunami-simple-atomic.py26
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