Move all of the parameters of the Root SimObject so they are
authorNathan Binkert <binkertn@umich.edu>
Tue, 6 Mar 2007 19:13:43 +0000 (11:13 -0800)
committerNathan Binkert <binkertn@umich.edu>
Tue, 6 Mar 2007 19:13:43 +0000 (11:13 -0800)
directly configured by python.  Move stuff from root.(cc|hh) to
core.(cc|hh) since it really belogs there now.
In the process, simplify how ticks are used in the python code.

--HG--
extra : convert_revision : cf82ee1ea20f9343924f30bacc2a38d4edee8df3

52 files changed:
configs/common/FSConfig.py
configs/common/Simulation.py
configs/example/fs.py
src/base/annotate.cc
src/base/misc.cc
src/base/pollevent.cc
src/base/pollevent.hh
src/base/trace.hh
src/cpu/o3/cpu.cc
src/cpu/o3/fetch_impl.hh
src/cpu/o3/inst_queue_impl.hh
src/cpu/ozone/inst_queue_impl.hh
src/cpu/pc_event.cc
src/cpu/static_inst.cc
src/dev/etherbus.cc
src/dev/etherdump.cc
src/dev/etherlink.cc
src/dev/ide_disk.cc
src/dev/pcidev.cc
src/kern/tru64/tru64.hh
src/mem/cache/cache_blk.hh
src/mem/cache/miss/mshr.cc
src/mem/cache/tags/iic.cc
src/mem/cache/tags/lru.cc
src/mem/cache/tags/split_lifo.cc
src/mem/cache/tags/split_lru.cc
src/mem/packet.hh
src/mem/request.hh
src/python/m5/__init__.py
src/python/m5/convert.py
src/python/m5/event.py [new file with mode: 0644]
src/python/m5/main.py
src/python/m5/objects/BaseCPU.py
src/python/m5/objects/PhysicalMemory.py
src/python/m5/objects/Root.py
src/python/m5/params.py
src/python/m5/ticks.py [new file with mode: 0644]
src/python/swig/core.i
src/python/swig/event.i
src/sim/builder.cc
src/sim/core.cc
src/sim/core.hh
src/sim/eventq.cc
src/sim/main.cc
src/sim/root.cc
src/sim/sim_events.cc
src/sim/sim_events.hh
tests/configs/t1000-simple-atomic.py
tests/configs/tsunami-simple-atomic-dual.py
tests/configs/tsunami-simple-atomic.py
tests/configs/tsunami-simple-timing-dual.py
tests/configs/tsunami-simple-timing.py

index da35698f2e158f57942d0b6683240e8d067834a7..be3f5ff79e49084e3676c544eacc9d23ecac6aef 100644 (file)
@@ -132,5 +132,4 @@ def makeDualRoot(testSystem, driveSystem, dumpfile):
         self.etherdump = EtherDump(file=dumpfile)
         self.etherlink.dump = Parent.etherdump
 
-    self.clock = '1THz'
     return self
index 8374d2fb59dc5f7bca7de6d393f83af1021083ad..61b14f0266c311534387f2002a25ceb5f600ebeb 100644 (file)
@@ -64,7 +64,7 @@ def run(options, root, testsys, cpu_class):
     if options.maxtick:
         maxtick = options.maxtick
     elif options.maxtime:
-        simtime = int(options.maxtime * root.clock.value)
+        simtime = m5.ticks.seconds(simtime)
         print "simulating for: ", simtime
         maxtick = simtime
     else:
index b878f2bd482d5b506c3b6c313a183c444a5702f8..bd4637e95c2e6058af474b63c2fbcae3408f1800 100644 (file)
@@ -137,7 +137,7 @@ if len(bm) == 2:
     drive_sys.cpu.connectMemPorts(drive_sys.membus)
     root = makeDualRoot(test_sys, drive_sys, options.etherdump)
 elif len(bm) == 1:
-    root = Root(clock = '1THz', system = test_sys)
+    root = Root(system=test_sys)
 else:
     print "Error I don't know how to create more than 2 systems."
     sys.exit(1)
index ba2fb1788ae670701d689aac8454e8775213efe2..de7eeed51f145dc5f7514dc71967da0b07c472f1 100644 (file)
@@ -32,7 +32,7 @@
 #include "base/callback.hh"
 #include "base/output.hh"
 #include "base/trace.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
 #include "sim/sim_exit.hh"
 #include "sim/system.hh"
 
index 29b6d2d88f61cef4c290ba2be0425f2b4bdf2349..afb48ca801064a19d7229e03b8750d229984d6ec 100644 (file)
@@ -38,7 +38,7 @@
 #include "base/trace.hh"
 #include "base/varargs.hh"
 #include "sim/host.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
 
 using namespace std;
 
index 32724b74de940d9c7818043952cd27c2fb857797..331b5eac6b1d3f019808f8c90b0e58be19dd3e8d 100644 (file)
@@ -42,7 +42,7 @@
 #include "sim/host.hh"
 #include "base/misc.hh"
 #include "base/pollevent.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
 #include "sim/serialize.hh"
 
 using namespace std;
index 5b84650cbf1825f83e608694be3bdc0e544c7368..ecaeb94ce9b2db4bfded43e14dcc461f5d4c6c0e 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <vector>
 #include <poll.h>
-#include "sim/root.hh"
+#include "sim/core.hh"
 
 class Checkpoint;
 class PollQueue;
index 8e380d8e13866ff4ab499b2aece20a1e787c1567..c1b5061870dfb53fef61dd022fa128b720289627 100644 (file)
@@ -39,7 +39,7 @@
 #include "base/match.hh"
 #include "base/traceflags.hh"
 #include "sim/host.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
 
 namespace Trace {
 
index 66c75a12df6f5d3bbcef3cf1f752ee723fdcdad4..785165636ea3211cfa73c483e9118dbb9f91216b 100644 (file)
@@ -45,7 +45,7 @@
 #include "cpu/o3/isa_specific.hh"
 #include "cpu/o3/cpu.hh"
 
-#include "sim/root.hh"
+#include "sim/core.hh"
 #include "sim/stat_control.hh"
 
 #if USE_CHECKER
index e6a7798234f94a37573d5423c3239ee9a04dd147..ac0149d1845d4ce75ef809e0aa20d291fb72d7bd 100644 (file)
@@ -40,7 +40,7 @@
 #include "mem/request.hh"
 #include "sim/byteswap.hh"
 #include "sim/host.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
 
 #if FULL_SYSTEM
 #include "arch/tlb.hh"
index 98b8fa9002a9e337c03c47b95d3d7d78519ccadf..d5781d89d787f329f80ed40217643251c9941ee9 100644 (file)
@@ -32,7 +32,7 @@
 #include <limits>
 #include <vector>
 
-#include "sim/root.hh"
+#include "sim/core.hh"
 
 #include "cpu/o3/fu_pool.hh"
 #include "cpu/o3/inst_queue.hh"
index 84f2b2a198d624910d4d09a47f88e641203db3c2..ea9d03c0dced2feccb37de74cd560e8a65ec087d 100644 (file)
@@ -38,7 +38,7 @@
 
 #include <vector>
 
-#include "sim/root.hh"
+#include "sim/core.hh"
 
 #include "cpu/ozone/inst_queue.hh"
 #if 0
index fca357fe316355bc5d83333812a5e20fb22d5026..7ab8bfcb88f0cef772860ede30d1082414d114bc 100644 (file)
@@ -40,7 +40,7 @@
 #include "cpu/thread_context.hh"
 #include "cpu/pc_event.hh"
 #include "sim/debug.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
 #include "sim/system.hh"
 
 using namespace std;
index cb4a7cdf7b6a8c33a7e085cf470825ca4b6435a9..64fcc058079b248a856445be469615d86005d62f 100644 (file)
@@ -31,7 +31,7 @@
 
 #include <iostream>
 #include "cpu/static_inst.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
 
 StaticInstPtr StaticInst::nullStaticInstPtr;
 
index 348bb818a05888adffb951c5b26e6f9b175abbf3..cedb3cd4dbf8ef08f8ab5db547697444cd8b1a13 100644 (file)
@@ -43,7 +43,7 @@
 #include "dev/etherint.hh"
 #include "dev/etherpkt.hh"
 #include "sim/builder.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
 
 using namespace std;
 
index 0c986cc2136da8bce41c7b8a724ac0ee3ad7eca6..04463f3ee4c85d06c7a42665e7118ee9238f8ce6 100644 (file)
@@ -41,7 +41,7 @@
 #include "base/output.hh"
 #include "dev/etherdump.hh"
 #include "sim/builder.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
 
 using std::string;
 
index cd3812270fd6357ead3f62b42f5cd26a0ad25ab0..5d30e17440f124c4bc6165e96ab84273fea3fb19 100644 (file)
@@ -47,7 +47,7 @@
 #include "sim/builder.hh"
 #include "sim/serialize.hh"
 #include "sim/system.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
 
 using namespace std;
 
index 5083c9c8d16f741ff1045d373eb26d527e0dbb05..9fa0cedded139a6f166e8befb4cb1e6a9b34d8a8 100644 (file)
@@ -48,7 +48,7 @@
 #include "dev/alpha/tsunami_pchip.hh"
 #include "sim/builder.hh"
 #include "sim/sim_object.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
 #include "arch/isa_traits.hh"
 
 using namespace std;
index 1c2465dd192cfd9cd8ccb6fea29a77dcf531c194..f906e69cf74a9fa03b7ae3ede73c1a6f873d2c10 100644 (file)
@@ -51,7 +51,7 @@
 #include "sim/builder.hh"
 #include "sim/byteswap.hh"
 #include "sim/param.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
 
 using namespace std;
 
index 82db34bf61eeec5422233288859fb236a2c8f514..6645aa86597bbe625dc51d9e9dd56ab220d5d8ab 100644 (file)
@@ -56,7 +56,7 @@ class Tru64 {};
 #include <unistd.h>
 
 #include "cpu/base.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
 #include "sim/syscall_emul.hh"
 
 typedef struct stat global_stat;
index a4df1b03ffd45a195c9d4367adad25d5873b10b0..fa00a0f5af5e670e0fc6df0f7dca7f0357501134 100644 (file)
@@ -37,7 +37,7 @@
 
 #include <list>
 
-#include "sim/root.hh"         // for Tick
+#include "sim/core.hh"         // for Tick
 #include "arch/isa_traits.hh"  // for Addr
 #include "mem/request.hh"
 
index 352d1ec6f3ba60ed1a131ebf7100e718defcf701..74dad658b4ed6a9baaf39649b548ce64282d5fd7 100644 (file)
@@ -39,7 +39,7 @@
 #include <vector>
 
 #include "mem/cache/miss/mshr.hh"
-#include "sim/root.hh" // for curTick
+#include "sim/core.hh" // for curTick
 #include "sim/host.hh"
 #include "base/misc.hh"
 #include "mem/cache/cache.hh"
index 20e2ef0ac6824749fbb7111a373c115e977e0aba..9c802d0dc69db44a5cdce206534bf0fa436c30f0 100644 (file)
@@ -42,7 +42,7 @@
 #include "mem/cache/base_cache.hh"
 #include "mem/cache/tags/iic.hh"
 #include "base/intmath.hh"
-#include "sim/root.hh" // for curTick
+#include "sim/core.hh" // for curTick
 
 #include "base/trace.hh" // for DPRINTF
 
index 102bb350643a482f082d495686f7483f38a41ea5..8e87797744c5582294a29260f68650a2ab8bbb35 100644 (file)
@@ -38,7 +38,7 @@
 #include "mem/cache/base_cache.hh"
 #include "base/intmath.hh"
 #include "mem/cache/tags/lru.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
 
 using namespace std;
 
index 792ff8fa72d46a69e4939258d59a9f80a6bfa073..d71d1a3efde25d1ad33ced9ef779017f801264ed 100644 (file)
@@ -38,7 +38,7 @@
 #include "mem/cache/base_cache.hh"
 #include "base/intmath.hh"
 #include "mem/cache/tags/split_lifo.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
 #include "base/trace.hh"
 
 using namespace std;
index c37d72cb7eaa8ec556e4f416aade75c4d77866cf..7227fb5c19ff2672ebc171595729608551077b11 100644 (file)
@@ -38,7 +38,7 @@
 #include "mem/cache/base_cache.hh"
 #include "base/intmath.hh"
 #include "mem/cache/tags/split_lru.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
 
 using namespace std;
 
index 16410594ae92f802a8cdaa24ad68a93b62fb1468..dc23e9f6da328ec53a40f24a0857d3ec7a858588 100644 (file)
@@ -46,7 +46,7 @@
 #include "base/misc.hh"
 #include "mem/request.hh"
 #include "sim/host.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
 
 
 struct Packet;
index 43d8ff1d5c7f300352ac9b30c8ce58787650c01f..d2ebc91d3eed31d49adfa176e2dcb1c45f637cce 100644 (file)
@@ -40,7 +40,7 @@
 #define __MEM_REQUEST_HH__
 
 #include "sim/host.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
 
 #include <cassert>
 
index 30ebcfe7d837476e7e597fc20f6716a5ae763e19..6eac7b6d7b0a3f1c945e6499697c33b4d3c58781 100644 (file)
@@ -36,7 +36,7 @@ import internal
 # import a few SWIG-wrapped items (those that are likely to be used
 # directly by user scripts) completely into this module for
 # convenience
-from internal.event import SimLoopExitEvent
+import event
 
 # import the m5 compile options
 import defines
@@ -80,7 +80,9 @@ env.update(os.environ)
 # The final hook to generate .ini files.  Called from the user script
 # once the config is built.
 def instantiate(root):
-    params.ticks_per_sec = float(root.clock.frequency)
+    # we need to fix the global frequency
+    ticks.fixGlobalFrequency()
+
     root.unproxy_all()
     # ugly temporary hack to get output to config.ini
     sys.stdout = file(os.path.join(options.outdir, 'config.ini'), 'w')
@@ -94,6 +96,7 @@ def instantiate(root):
     # Initialize the global statistics
     internal.stats.initSimStats()
 
+    # Create the C++ sim objects and connect ports
     root.createCCObject()
     root.connectPorts()
 
@@ -136,7 +139,7 @@ def simulate(*args, **kwargs):
 
 # Export curTick to user script.
 def curTick():
-    return internal.event.cvar.curTick
+    return internal.core.cvar.curTick
 
 # Python exit handlers happen in reverse order.  We want to dump stats last.
 atexit.register(internal.stats.dump)
index 580a579bceedc0739d5c2c79a06dedabae1170e9..bb9e3e1f1feca7d1ab339979cb2878b4be250aa3 100644 (file)
@@ -148,7 +148,7 @@ def toLatency(value):
 
     raise ValueError, "cannot convert '%s' to latency" % value
 
-def toClockPeriod(value):
+def anyToLatency(value):
     """result is a clock period"""
 
     if not isinstance(value, str):
@@ -170,6 +170,27 @@ def toClockPeriod(value):
 
     raise ValueError, "cannot convert '%s' to clock period" % value
 
+def anyToFrequency(value):
+    """result is a clock period"""
+
+    if not isinstance(value, str):
+        raise TypeError, "wrong type '%s' should be str" % type(value)
+
+    try:
+        val = toFrequency(value)
+        return val
+    except ValueError:
+        pass
+
+    try:
+        val = toLatency(value)
+        if val != 0:
+            val = 1 / val
+        return val
+    except ValueError:
+        pass
+
+    raise ValueError, "cannot convert '%s' to clock period" % value
 
 def toNetworkBandwidth(value):
     if not isinstance(value, str):
diff --git a/src/python/m5/event.py b/src/python/m5/event.py
new file mode 100644 (file)
index 0000000..2d64974
--- /dev/null
@@ -0,0 +1,42 @@
+# Copyright (c) 2006 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Nathan Binkert
+
+from internal.event import create
+from internal.event import SimLoopExitEvent as SimExit
+
+class ProgressEvent(object):
+    def __init__(self, period):
+        self.period = int(period)
+        self.schedule()
+
+    def schedule(self):
+        create(self, m5.curTick() + self.period)
+
+    def __call__(self):
+        print "Progress! Time now %fs" % (m5.curTick()/1e12)
+        self.schedule()
index 54368b91ef13f50863606215dc60137658203326..1695ed75f57a91d3f549d7ac43652f54a0739fc7 100644 (file)
@@ -188,6 +188,7 @@ def parse_args():
 
 def main():
     import defines
+    import event
     import info
     import internal
 
@@ -295,7 +296,7 @@ def main():
     if options.trace_start:
         def enable_trace():
             internal.trace.cvar.enabled = True
-        internal.event.create(enable_trace, int(options.trace_start))
+        event.create(enable_trace, int(options.trace_start))
     else:
         internal.trace.cvar.enabled = True
 
index 67a28a61e111bf59a041b30ce661566e3c965155..986220c3fa183b361c1a242c97b20bb1cebaece6 100644 (file)
@@ -47,8 +47,8 @@ class BaseCPU(SimObject):
     defer_registration = Param.Bool(False,
         "defer registration with system (for sampling)")
 
-    clock = Param.Clock(Parent.clock, "clock speed")
-    phase = Param.Latency("0ns", "clock phase")
+    clock = Param.Clock('1t', "clock speed")
+    phase = Param.Latency('0ns', "clock phase")
 
     _mem_ports = []
 
index b8df6229eccf9a197bcface6287fde03950ea978..c389e4a7ff3d6c349ed112369ec4af18d4e515fd 100644 (file)
@@ -8,7 +8,7 @@ class PhysicalMemory(MemObject):
     functional = Port("Functional Access Port")
     range = Param.AddrRange(AddrRange('128MB'), "Device Address")
     file = Param.String('', "memory mapped file")
-    latency = Param.Latency(Parent.clock, "latency of an access")
+    latency = Param.Latency('1t', "latency of an access")
     zero = Param.Bool(False, "zero initialize memory")
 
 class DRAMMemory(PhysicalMemory):
index 8db4fa5a23be9c18609435fd68da6d2e448f54f2..2b0e736e78dd551b522c70910759b08434c11787 100644 (file)
@@ -3,9 +3,4 @@ from m5.params import *
 
 class Root(SimObject):
     type = 'Root'
-    clock = Param.RootClock('1THz', "tick frequency")
-    max_tick = Param.Tick('0', "maximum simulation ticks (0 = infinite)")
-    progress_interval = Param.Tick('0',
-        "print a progress message every n ticks (0 = never)")
-    output_file = Param.String('cout', "file to dump simulator output to")
-    checkpoint = Param.String('', "checkpoint file to load")
+    dummy = Param.Int(0, "We don't support objects without params")
index e71e1c3c52a88e06160419ed6df2702a9bf5b8ae..7c60a855421f46e3706ed29120de40c488489140 100644 (file)
@@ -51,6 +51,7 @@ import sys
 import time
 
 import convert
+import ticks
 from util import *
 
 # Dummy base class to identify types that are legitimate for SimObject
@@ -632,47 +633,29 @@ class Enum(ParamValue):
     def __str__(self):
         return self.value
 
-ticks_per_sec = None
-
 # how big does a rounding error need to be before we warn about it?
 frequency_tolerance = 0.001  # 0.1%
 
-# convert a floting-point # of ticks to integer, and warn if rounding
-# discards too much precision
-def tick_check(float_ticks):
-    if float_ticks == 0:
-        return 0
-    int_ticks = int(round(float_ticks))
-    err = (float_ticks - int_ticks) / float_ticks
-    if err > frequency_tolerance:
-        print >> sys.stderr, "Warning: rounding error > tolerance"
-        print >> sys.stderr, "    %f rounded to %d" % (float_ticks, int_ticks)
-        #raise ValueError
-    return int_ticks
-
-def getLatency(value):
-    if isinstance(value, Latency) or isinstance(value, Clock):
-        return value.value
-    elif isinstance(value, Frequency) or isinstance(value, RootClock):
-        return 1 / value.value
-    elif isinstance(value, str):
-        try:
-            return convert.toLatency(value)
-        except ValueError:
-            try:
-                return 1 / convert.toFrequency(value)
-            except ValueError:
-                pass # fall through
-    raise ValueError, "Invalid Frequency/Latency value '%s'" % value
-
-
-class Latency(NumericParamValue):
+class TickParamValue(NumericParamValue):
     cxx_type = 'Tick'
     cxx_predecls = ['#include "sim/host.hh"']
     swig_predecls = ['%import "python/m5/swig/stdint.i"\n' +
                      '%import "sim/host.hh"']
+
+class Latency(TickParamValue):
     def __init__(self, value):
-        self.value = getLatency(value)
+        if isinstance(value, (Latency, Clock)):
+            self.ticks = value.ticks
+            self.value = value.value
+        elif isinstance(value, Frequency):
+            self.ticks = value.ticks
+            self.value = 1.0 / value.value
+        elif value.endswith('t'):
+            self.ticks = True
+            self.value = int(value[:-1])
+        else:
+            self.ticks = False
+            self.value = convert.toLatency(value)
 
     def __getattr__(self, attr):
         if attr in ('latency', 'period'):
@@ -683,15 +666,25 @@ class Latency(NumericParamValue):
 
     # convert latency to ticks
     def ini_str(self):
-        return str(tick_check(self.value * ticks_per_sec))
+        if self.ticks or self.value == 0:
+            return '%d' % self.value
+        else:
+            return '%d' % (ticks.fromSeconds(self.value))
 
-class Frequency(NumericParamValue):
-    cxx_type = 'Tick'
-    cxx_predecls = ['#include "sim/host.hh"']
-    swig_predecls = ['%import "python/m5/swig/stdint.i"\n' +
-                     '%import "sim/host.hh"']
+class Frequency(TickParamValue):
     def __init__(self, value):
-        self.value = 1 / getLatency(value)
+        if isinstance(value, (Latency, Clock)):
+            if value.value == 0:
+                self.value = 0
+            else:
+                self.value = 1.0 / value.value
+            self.ticks = value.ticks
+        elif isinstance(value, Frequency):
+            self.value = value.value
+            self.ticks = value.ticks
+        else:
+            self.ticks = False
+            self.value = convert.toFrequency(value)
 
     def __getattr__(self, attr):
         if attr == 'frequency':
@@ -700,30 +693,12 @@ class Frequency(NumericParamValue):
             return Latency(self)
         raise AttributeError, "Frequency object has no attribute '%s'" % attr
 
-    # convert frequency to ticks per period
-    def ini_str(self):
-        return self.period.ini_str()
-
-# Just like Frequency, except ini_str() is absolute # of ticks per sec (Hz).
-# We can't inherit from Frequency because we don't want it to be directly
-# assignable to a regular Frequency parameter.
-class RootClock(ParamValue):
-    cxx_type = 'Tick'
-    cxx_predecls = ['#include "sim/host.hh"']
-    swig_predecls = ['%import "python/m5/swig/stdint.i"\n' +
-                     '%import "sim/host.hh"']
-    def __init__(self, value):
-        self.value = 1 / getLatency(value)
-
-    def __getattr__(self, attr):
-        if attr == 'frequency':
-            return Frequency(self)
-        if attr in ('latency', 'period'):
-            return Latency(self)
-        raise AttributeError, "Frequency object has no attribute '%s'" % attr
-
+    # convert latency to ticks
     def ini_str(self):
-        return str(tick_check(self.value))
+        if self.ticks or self.value == 0:
+            return '%d' % self.value
+        else:
+            return '%d' % (ticks.fromSeconds(1.0 / self.value))
 
 # A generic frequency and/or Latency value.  Value is stored as a latency,
 # but to avoid ambiguity this object does not support numeric ops (* or /).
@@ -734,7 +709,18 @@ class Clock(ParamValue):
     swig_predecls = ['%import "python/m5/swig/stdint.i"\n' +
                      '%import "sim/host.hh"']
     def __init__(self, value):
-        self.value = getLatency(value)
+        if isinstance(value, (Latency, Clock)):
+            self.ticks = value.ticks
+            self.value = value.value
+        elif isinstance(value, Frequency):
+            self.ticks = value.ticks
+            self.value = 1.0 / value.value
+        elif value.endswith('t'):
+            self.ticks = True
+            self.value = int(value[:-1])
+        else:
+            self.ticks = False
+            self.value = convert.anyToLatency(value)
 
     def __getattr__(self, attr):
         if attr == 'frequency':
@@ -749,18 +735,23 @@ class Clock(ParamValue):
 class NetworkBandwidth(float,ParamValue):
     cxx_type = 'float'
     def __new__(cls, value):
-        val = convert.toNetworkBandwidth(value) / 8.0
+        # convert to bits per second
+        val = convert.toNetworkBandwidth(value)
         return super(cls, NetworkBandwidth).__new__(cls, val)
 
     def __str__(self):
         return str(self.val)
 
     def ini_str(self):
-        return '%f' % (ticks_per_sec / float(self))
+        # convert to seconds per byte
+        value = 8.0 / float(self)
+        # convert to ticks per byte
+        return '%f' % (ticks.fromSeconds(value))
 
 class MemoryBandwidth(float,ParamValue):
     cxx_type = 'float'
     def __new__(self, value):
+        # we want the number of ticks per byte of data
         val = convert.toMemoryBandwidth(value)
         return super(cls, MemoryBandwidth).__new__(cls, val)
 
@@ -768,7 +759,10 @@ class MemoryBandwidth(float,ParamValue):
         return str(self.val)
 
     def ini_str(self):
-        return '%f' % (ticks_per_sec / float(self))
+        # convert to seconds per byte
+        value = 1.0 / float(self)
+        # convert to ticks per byte
+        return '%f' % (ticks.fromSeconds(value))
 
 #
 # "Constants"... handy aliases for various values.
@@ -1023,7 +1017,7 @@ __all__ = ['Param', 'VectorParam',
            'Counter', 'Addr', 'Tick', 'Percent',
            'TcpPort', 'UdpPort', 'EthernetAddr',
            'MemorySize', 'MemorySize32',
-           'Latency', 'Frequency', 'RootClock', 'Clock',
+           'Latency', 'Frequency', 'Clock',
            'NetworkBandwidth', 'MemoryBandwidth',
            'Range', 'AddrRange', 'TickRange',
            'MaxAddr', 'MaxTick', 'AllMemory',
diff --git a/src/python/m5/ticks.py b/src/python/m5/ticks.py
new file mode 100644 (file)
index 0000000..e91b470
--- /dev/null
@@ -0,0 +1,89 @@
+# Copyright (c) 2007 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Nathan Binkert
+
+import sys
+
+import convert
+import internal
+
+tps = 1.0e12         # default to 1 THz (1 Tick == 1 ps)
+tps_fixed = False    # once set to true, can't be changed
+
+# fix the global frequency and tell C++ about it
+def fixGlobalFrequency():
+    global tps, tps_fixed
+    if not tps_fixed:
+        tps_fixed = True
+        internal.core.setClockFrequency(int(tps))
+        print "Global frequency set at %d ticks per second" % int(tps)
+
+def setGlobalFrequency(ticksPerSecond):
+    global tps, tps_fixed
+
+    if tps_fixed:
+        raise AttributeError, \
+              "Global frequency already fixed at %f ticks/s." % tps
+
+    if isinstance(ticksPerSecond, (int, long)):
+        tps = ticksPerSecond
+    elif isinstance(ticksPerSecond, float):
+        tps = ticksPerSecond
+    elif isinstance(ticksPerSecond, str):
+        tps = round(convert.anyToFrequency(ticksPerSecond))
+    else:
+        raise TypeError, \
+              "wrong type '%s' for ticksPerSecond" % type(ticksPerSecond)
+
+# how big does a rounding error need to be before we warn about it?
+frequency_tolerance = 0.001  # 0.1%
+
+def fromSeconds(value):
+    if not isinstance(value, float):
+        raise TypeError, "can't convert '%s' to type tick" % type(value)
+
+    # once someone needs to convert to seconds, the global frequency
+    # had better be fixed
+    if not tps_fixed:
+        raise AttributeError, \
+              "In order to do conversions, the global frequency must be fixed"
+
+    if value == 0:
+        return 0
+
+    # convert the value from time to ticks
+    value *= tps
+
+    int_value = int(round(value))
+    err = (value - int_value) / value
+    if err > frequency_tolerance:
+        print >>sys.stderr, "Warning: rounding error > tolerance"
+        print >>sys.stderr, "    %f rounded to %d" % (value, int_value)
+    return int_value
+
+__all__ = [ 'setGlobalFrequency', 'fixGlobalFrequency', 'fromSeconds',
+            'frequency_tolerance' ]
index 1168907636e6097a073fac1a7676b72e4aae02b5..3edfa4c7edae4a80f8dc62ac514b23382a47de97 100644 (file)
 extern const char *compileDate;
 %}
 
+%include "stdint.i"
 %include "std_string.i"
+%include "sim/host.hh"
 
 void setOutputDir(const std::string &dir);
+void setOutputFile(const std::string &file);
 void loadIniFile(PyObject *);
 void SimStartup();
 void doExitCleanup();
 
 char *compileDate;
 
+void setClockFrequency(Tick ticksPerSecond);
+
+%immutable curTick;
+Tick curTick;
+
 %wrapper %{
 // fix up module name to reflect the fact that it's inside the m5 package
 #undef SWIG_name
index 51d7d89f0f04121c8aeb0304c4655abb39212732..9a2093c99377715e7976c455557a7e9a4ad4a564 100644 (file)
@@ -53,9 +53,6 @@ class CountedDrainEvent : public Event {
 CountedDrainEvent *createCountedDrain();
 void cleanupCountedDrain(Event *drain_event);
 
-%immutable curTick;
-Tick curTick;
-
 // minimal definition of SimExitEvent interface to wrap
 class SimLoopExitEvent {
   public:
@@ -74,8 +71,6 @@ class SimLoopExitEvent {
 SimLoopExitEvent *simulate(Tick num_cycles = MaxTick);
 void exitSimLoop(const std::string &message, int exit_code);
 
-Tick curTick;
-
 %wrapper %{
 // fix up module name to reflect the fact that it's inside the m5 package
 #undef SWIG_name
index 8ef54ce525088455ab4923c2c6d97f46ad55d7fc..532df36b11696c6b47c9313432243877923b374b 100644 (file)
@@ -35,7 +35,7 @@
 #include "sim/builder.hh"
 #include "sim/host.hh"
 #include "sim/sim_object.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
 
 using namespace std;
 
index 24cc33da2172c146c55858d9630764a6f38dd5cd..c961e9eb8ed7255c3f560c2f9220e6db446b0731 100644 (file)
 
 #include "base/callback.hh"
 #include "base/output.hh"
+#include "sim/core.hh"
 
 using namespace std;
 
+Tick curTick = 0;
+
+namespace Clock {
+/// The simulated frequency of curTick. (In ticks per second)
+Tick Frequency;
+
+namespace Float {
+double s;
+double ms;
+double us;
+double ns;
+double ps;
+
+double Hz;
+double kHz;
+double MHz;
+double GHZ;
+/* namespace Float */ }
+
+namespace Int {
+Tick s;
+Tick ms;
+Tick us;
+Tick ns;
+Tick ps;
+/* namespace Float */ }
+
+/* namespace Clock */ }
+
+void
+setClockFrequency(Tick ticksPerSecond)
+{
+    using namespace Clock;
+    Frequency = ticksPerSecond;
+    Float::s = static_cast<double>(Frequency);
+    Float::ms = Float::s / 1.0e3;
+    Float::us = Float::s / 1.0e6;
+    Float::ns = Float::s / 1.0e9;
+    Float::ps = Float::s / 1.0e12;
+
+    Float::Hz  = 1.0 / Float::s;
+    Float::kHz = 1.0 / Float::ms;
+    Float::MHz = 1.0 / Float::us;
+    Float::GHZ = 1.0 / Float::ns;
+
+    Int::s  = Frequency;
+    Int::ms = Int::s / 1000;
+    Int::us = Int::ms / 1000;
+    Int::ns = Int::us / 1000;
+    Int::ps = Int::ns / 1000;
+
+}
+
 void
 setOutputDir(const string &dir)
 {
     simout.setDirectory(dir);
 }
 
+ostream *outputStream;
+ostream *configStream;
+
+void
+setOutputFile(const string &file)
+{
+    outputStream = simout.find(file);
+}
+
 /**
  * Queue of C++ callbacks to invoke on simulator exit.
  */
@@ -74,3 +137,4 @@ doExitCleanup()
 
     cout.flush();
 }
+
index 2ef21c4b60b04217957ce2fe77b4ada2540a353e..7360032c27e727aebf194659f80184501fb6d4b3 100644 (file)
  *          Steve Reinhardt
  */
 
-#include <Python.h>
+#ifndef __SIM_CORE_HH__
+#define __SIM_CORE_HH__
+
 #include <string>
 
-#include "base/callback.hh"
+#include "sim/host.hh"
+
+/// The universal simulation clock.
+extern Tick curTick;
+const Tick retryTime = 1000;
+
+namespace Clock {
+/// The simulated frequency of curTick.
+extern Tick Frequency;
+
+namespace Float {
+extern double s;
+extern double ms;
+extern double us;
+extern double ns;
+extern double ps;
+
+extern double Hz;
+extern double kHz;
+extern double MHz;
+extern double GHZ;
+/* namespace Float */ }
 
+namespace Int {
+extern Tick s;
+extern Tick ms;
+extern Tick us;
+extern Tick ns;
+extern Tick ps;
+/* namespace Int */ }
+/* namespace Clock */ }
+
+void setClockFrequency(Tick ticksPerSecond);
+
+/// Output stream for simulator messages (e.g., cprintf()).  Also used
+/// as default stream for tracing and DPRINTF() messages (unless
+/// overridden with trace:file option).
+extern std::ostream *outputStream;
+void setOutputFile(const std::string &file);
 void setOutputDir(const std::string &dir);
 
+/// Output stream for configuration dump.
+extern std::ostream *configStream;
+
+struct Callback;
 void registerExitCallback(Callback *callback);
 void doExitCleanup();
+
+#endif /* __SIM_CORE_HH__ */
index 356472d9a7ee52218d9d78e4b4bc672a8c585ce0..bcd0d3df3f4e287b3f9689fcadfa8b0f5f19281d 100644 (file)
@@ -41,7 +41,7 @@
 
 #include "sim/eventq.hh"
 #include "base/trace.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
 
 using namespace std;
 
index 0341b7d5f0e4aaddeba5196101a1c2b51b85aa24..5bf4add4b47fd17f74d30f76aabaea099e98de84 100644 (file)
@@ -40,7 +40,7 @@
 #include "python/swig/init.hh"
 #include "sim/async.hh"
 #include "sim/host.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
 
 using namespace std;
 
index 565b57269ca0290ca8bfb19c271f14758b59f7d5..f4743af0a49d2b2151f231de19ad688699f09b32 100644 (file)
 #include <vector>
 
 #include "base/misc.hh"
-#include "base/output.hh"
 #include "sim/builder.hh"
-#include "sim/host.hh"
-#include "sim/sim_events.hh"
-#include "sim/sim_exit.hh"
 #include "sim/sim_object.hh"
-#include "sim/root.hh"
-
-using namespace std;
-
-Tick curTick = 0;
-ostream *outputStream;
-ostream *configStream;
-
-/// The simulated frequency of curTick. (This is only here for a short time)
-Tick ticksPerSecond;
-
-namespace Clock {
-/// The simulated frequency of curTick. (In ticks per second)
-Tick Frequency;
-
-namespace Float {
-double s;
-double ms;
-double us;
-double ns;
-double ps;
-
-double Hz;
-double kHz;
-double MHz;
-double GHZ;
-/* namespace Float */ }
-
-namespace Int {
-Tick s;
-Tick ms;
-Tick us;
-Tick ns;
-Tick ps;
-/* namespace Float */ }
-
-/* namespace Clock */ }
-
 
 // Dummy Object
-class Root : public SimObject
+struct Root : public SimObject
 {
-  private:
-    Tick max_tick;
-    Tick progress_interval;
-
-  public:
-    Root(const std::string &name, Tick maxtick, Tick pi)
-        : SimObject(name), max_tick(maxtick), progress_interval(pi)
-    {}
-
-    virtual void startup();
+    Root(const std::string &name) : SimObject(name) {}
 };
 
-void
-Root::startup()
-{
-    if (max_tick != 0)
-        schedExitSimLoop("reached maximum cycle count", curTick + max_tick);
-
-    if (progress_interval != 0)
-        new ProgressEvent(&mainEventQueue, progress_interval);
-}
-
 BEGIN_DECLARE_SIM_OBJECT_PARAMS(Root)
 
-    Param<Tick> clock;
-    Param<Tick> max_tick;
-    Param<Tick> progress_interval;
-    Param<string> output_file;
+    Param<int> dummy; // needed below
 
 END_DECLARE_SIM_OBJECT_PARAMS(Root)
 
 BEGIN_INIT_SIM_OBJECT_PARAMS(Root)
 
-    INIT_PARAM(clock, "tick frequency"),
-    INIT_PARAM(max_tick, "maximum simulation time"),
-    INIT_PARAM(progress_interval, "print a progress message"),
-    INIT_PARAM(output_file, "file to dump simulator output to")
+    INIT_PARAM(dummy, "")  // All SimObjects must have params
 
 END_INIT_SIM_OBJECT_PARAMS(Root)
 
@@ -132,29 +65,7 @@ CREATE_SIM_OBJECT(Root)
 
     created = true;
 
-    outputStream = simout.find(output_file);
-    Root *root = new Root(getInstanceName(), max_tick, progress_interval);
-
-    using namespace Clock;
-    Frequency = clock;
-    Float::s = static_cast<double>(Frequency);
-    Float::ms = Float::s / 1.0e3;
-    Float::us = Float::s / 1.0e6;
-    Float::ns = Float::s / 1.0e9;
-    Float::ps = Float::s / 1.0e12;
-
-    Float::Hz  = 1.0 / Float::s;
-    Float::kHz = 1.0 / Float::ms;
-    Float::MHz = 1.0 / Float::us;
-    Float::GHZ = 1.0 / Float::ns;
-
-    Int::s  = Frequency;
-    Int::ms = Int::s / 1000;
-    Int::us = Int::ms / 1000;
-    Int::ns = Int::us / 1000;
-    Int::ps = Int::ns / 1000;
-
-    return root;
+    return  new Root(getInstanceName());
 }
 
 REGISTER_SIM_OBJECT("Root", Root)
index 2ccc9dad20047236ffb795a694cbefc6fbde0d0d..a4457a11ca04d18a0de0f3fb470aaab8be40c0aa 100644 (file)
@@ -158,21 +158,3 @@ CheckSwapEvent::description()
 {
     return "check swap";
 }
-
-//
-// handle progress event: print message and reschedule
-//
-void
-ProgressEvent::process()
-{
-    DPRINTFN("ProgressEvent\n");
-    // reschedule for next interval
-    schedule(curTick + interval);
-}
-
-
-const char *
-ProgressEvent::description()
-{
-    return "progress message";
-}
index e1576b38cb71396c5b53c41a523550f3bccd5a12..94e2540b1abe345f3a56c94a3587bcb5cdf5b1c3 100644 (file)
@@ -125,23 +125,4 @@ class CheckSwapEvent : public Event
     virtual const char *description();
 };
 
-//
-// Progress event: print out cycle every so often so we know we're
-// making forward progress.
-//
-class ProgressEvent : public Event
-{
-  protected:
-    Tick interval;
-
-  public:
-    ProgressEvent(EventQueue *q, Tick ival)
-        : Event(q), interval(ival)
-    { schedule(curTick + interval); }
-
-    void process();    // process event
-
-    virtual const char *description();
-};
-
 #endif  // __SIM_SIM_EVENTS_HH__
index 51745892a34ff5936b91eca12e7a3e7234c60070..6a078e715258e63b76215bbf6946f4ec06b19fda 100644 (file)
@@ -36,4 +36,6 @@ system = FSConfig.makeSparcSystem('atomic')
 system.cpu = cpu
 cpu.connectMemPorts(system.membus)
 
-root = Root(clock = '2GHz', system = system)
+root = Root(system=system)
+
+m5.ticks.setGlobalFrequency('2GHz')
index 4adb328684fc51e4bb6fecc73e791d71efcfffc3..7ed854f44d3cc11c781e9376c0203629fbdd658b 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2006 The Regents of The University of Michigan
+# Copyright (c) 2006-2007 The Regents of The University of Michigan
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -37,4 +37,6 @@ system.cpu = cpus
 for c in cpus:
     c.connectMemPorts(system.membus)
 
-root = Root(clock = '2GHz', system = system)
+root = Root(system=system)
+
+m5.ticks.setGlobalFrequency('2GHz')
index 653df9bb0d68174e420e56584bbea356130df77a..4859f30cf4dbff3a5fb48d9ba6b3abb1e7b7670d 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2006 The Regents of The University of Michigan
+# Copyright (c) 2006-2007 The Regents of The University of Michigan
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -36,4 +36,5 @@ system = FSConfig.makeLinuxAlphaSystem('atomic')
 system.cpu = cpu
 cpu.connectMemPorts(system.membus)
 
-root = Root(clock = '2GHz', system = system)
+root = Root(system=system)
+m5.ticks.setGlobalFrequency('2GHz')
index bfd478969cfdcac72deb26698b5afdea84392abc..0c8c3d5236710c703a52318c5077f6ba5c6eecfe 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2006 The Regents of The University of Michigan
+# Copyright (c) 2006-2007 The Regents of The University of Michigan
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -37,4 +37,5 @@ system.cpu = cpus
 for c in cpus:
     c.connectMemPorts(system.membus)
 
-root = Root(clock = '2GHz', system = system)
+root = Root(system=system)
+m5.ticks.setGlobalFrequency('2GHz')
index 59401c040f54c49bd21bfe933f3e87748fecf9b0..9f532e3ae45917b57fba50fbc944fbad3f7dbb10 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2006 The Regents of The University of Michigan
+# Copyright (c) 2006-2007 The Regents of The University of Michigan
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -36,4 +36,5 @@ system = FSConfig.makeLinuxAlphaSystem('timing')
 system.cpu = cpu
 cpu.connectMemPorts(system.membus)
 
-root = Root(clock = '2GHz', system = system)
+root = Root(system=system)
+m5.ticks.setGlobalFrequency('2GHz')