/* * Copyright (c) 2014 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. * * Copyright (c) 2006 The Regents of The University of Michigan * Copyright (c) 2013 Advanced Micro Devices, Inc. * Copyright (c) 2013 Mark D. Hill and David A. Wood * 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 * Steve Reinhardt * Andrew Bardsley */ /** * @file * * Defines an sc_module type to wrap a gem5 simulation. The 'evaluate' * thread on that module implements the gem5 event loop. * * This currently only supports a single event queue and strictly * cooperatively threaded SystemC threads and so there should be at * most one Gem5Module instantiated in any simulation. */ #ifndef __SIM_SC_MODULE_HH__ #define __SIM_SC_MODULE_HH__ #include #include "sim/eventq.hh" #include "sim/sim_events.hh" namespace Gem5SystemC { /** A SystemC module implementing the gem5 event queue. This object * doesn't actually own any of the simulation SimObjects (those need * to be administered separately) but it does control the event * queue. * * The event loop here services gem5 events in order at the current time * and then yielding to another SystemC thread. gem5 events are not * individually scheduled in SystemC. For this reason, asynchronous events * and function interaction (for example TLM) with gem5 from SystemC must * notify the module so that the yielding 'wait' can be interrupted. * From the point of view of another SystemC module calling into gem5, * curTick can lag SystemC time, be exactly the same time but *never* * lead SystemC time. * * This functionality is wrapped in an sc_module as its intended that * the a class representing top level simulation control should be derived * from this class. */ class Module : public sc_core::sc_module { protected: /** Event to trigger (via. ::notify) for event scheduling from * outside gem5 */ sc_core::sc_event externalSchedulingEvent; /** Event to trigger on exit of eventLoop */ sc_core::sc_event eventLoopExitEvent; /** Event to trigger to enter eventLoop */ sc_core::sc_event eventLoopEnterEvent; /** Expected exit time of last eventLoop sleep */ Tick wait_exit_time; /** Are we in Module::simulate? Used to mask events when not inside * the simulate loop */ bool in_simulate; /** Placeholder base class for a variant event queue if this becomes * useful */ class SCEventQueue : public EventQueue { protected: Module &module; public: SCEventQueue(const std::string &name, Module &module_) : EventQueue(name), module(module_) { } /** Signal module to wakeup */ void wakeup(Tick when); }; /** Service any async event marked up in the globals event_... */ void serviceAsyncEvent(); public: /** Simulate is a process */ SC_HAS_PROCESS(Module); Module(sc_core::sc_module_name name); /** Last exitEvent from eventLoop */ Event *exitEvent; /** Setup global event queues. Call this before any other event queues * are created */ static void setupEventQueues(Module &module); /** Catch gem5 time up with SystemC */ void catchup(); /** Notify an externalSchedulingEvent at the given time from the * current SystemC time */ void notify(sc_core::sc_time time_from_now = sc_core::SC_ZERO_TIME); /** Process an event triggered by externalSchedulingEvent and also * call eventLoop (to try and mop up any events at this time) if there * are any scheduled events */ void serviceExternalEvent(); /** Process gem5 events up until an exit event or there are no events * left. */ void eventLoop(); /** Run eventLoop up to num_cycles and return the final event */ GlobalSimLoopExitEvent *simulate(Tick num_cycles = MaxTick); }; /** There are assumptions throughout Gem5SystemC file that a tick is 1ps. * Make this the case */ void setTickFrequency(); } #endif // __SIM_SC_MODULE_HH__