113372Sgabeblack@google.com/*
213372Sgabeblack@google.com * Copyright (c) 2014 ARM Limited
313372Sgabeblack@google.com * All rights reserved
413372Sgabeblack@google.com *
513372Sgabeblack@google.com * The license below extends only to copyright in the software and shall
613372Sgabeblack@google.com * not be construed as granting a license to any other intellectual
713372Sgabeblack@google.com * property including but not limited to intellectual property relating
813372Sgabeblack@google.com * to a hardware implementation of the functionality of the software
913372Sgabeblack@google.com * licensed hereunder.  You may use the software subject to the license
1013372Sgabeblack@google.com * terms below provided that you ensure that this notice is replicated
1113372Sgabeblack@google.com * unmodified and in its entirety in all distributions of the software,
1213372Sgabeblack@google.com * modified or unmodified, in source code or in binary form.
1313372Sgabeblack@google.com *
1413372Sgabeblack@google.com * Copyright (c) 2006 The Regents of The University of Michigan
1513372Sgabeblack@google.com * Copyright (c) 2013 Advanced Micro Devices, Inc.
1613372Sgabeblack@google.com * Copyright (c) 2013 Mark D. Hill and David A. Wood
1713372Sgabeblack@google.com * All rights reserved.
1813372Sgabeblack@google.com *
1913372Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
2013372Sgabeblack@google.com * modification, are permitted provided that the following conditions are
2113372Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
2213372Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
2313372Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
2413372Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
2513372Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
2613372Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
2713372Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
2813372Sgabeblack@google.com * this software without specific prior written permission.
2913372Sgabeblack@google.com *
3013372Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3113372Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3213372Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3313372Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3413372Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3513372Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3613372Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3713372Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3813372Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3913372Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
4013372Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4113372Sgabeblack@google.com *
4213372Sgabeblack@google.com * Authors: Nathan Binkert
4313372Sgabeblack@google.com *          Steve Reinhardt
4413372Sgabeblack@google.com *          Andrew Bardsley
4513372Sgabeblack@google.com *          Christian Menard
4613372Sgabeblack@google.com */
4713372Sgabeblack@google.com
4813372Sgabeblack@google.com/**
4913372Sgabeblack@google.com * @file
5013372Sgabeblack@google.com *
5113372Sgabeblack@google.com * Defines an sc_module type to wrap a gem5 simulation.  The 'evaluate'
5213372Sgabeblack@google.com * thread on that module implements the gem5 event loop.
5313372Sgabeblack@google.com *
5413372Sgabeblack@google.com * This currently only supports a single event queue and strictly
5513372Sgabeblack@google.com * cooperatively threaded SystemC threads and so there should be at
5613372Sgabeblack@google.com * most one Gem5Module instantiated in any simulation.
5713372Sgabeblack@google.com */
5813372Sgabeblack@google.com
5913372Sgabeblack@google.com#ifndef __SIM_SC_MODULE_HH__
6013372Sgabeblack@google.com#define __SIM_SC_MODULE_HH__
6113372Sgabeblack@google.com
6213372Sgabeblack@google.com#include <systemc>
6313372Sgabeblack@google.com
6413372Sgabeblack@google.com#include "sim/eventq.hh"
6513372Sgabeblack@google.com#include "sim/sim_events.hh"
6613372Sgabeblack@google.com
6713372Sgabeblack@google.comnamespace Gem5SystemC
6813372Sgabeblack@google.com{
6913372Sgabeblack@google.com
7013372Sgabeblack@google.com/** A SystemC module implementing the gem5 event queue.  This object
7113372Sgabeblack@google.com *  doesn't actually own any of the simulation SimObjects (those need
7213372Sgabeblack@google.com *  to be administered separately) but it does control the event
7313372Sgabeblack@google.com *  queue.
7413372Sgabeblack@google.com *
7513372Sgabeblack@google.com *  The event loop here services gem5 events in order at the current time
7613372Sgabeblack@google.com *  and then yielding to another SystemC thread.  gem5 events are not
7713372Sgabeblack@google.com *  individually scheduled in SystemC.  For this reason, asynchronous events
7813372Sgabeblack@google.com *  and function interaction (for example TLM) with gem5 from SystemC must
7913372Sgabeblack@google.com *  notify the module so that the yielding 'wait' can be interrupted.
8013372Sgabeblack@google.com *  From the point of view of another SystemC module calling into gem5,
8113372Sgabeblack@google.com *  curTick can lag SystemC time, be exactly the same time but *never*
8213372Sgabeblack@google.com *  lead SystemC time.
8313372Sgabeblack@google.com *
8413372Sgabeblack@google.com *  This functionality is wrapped in an sc_module as its intended that
8513372Sgabeblack@google.com *  the a class representing top level simulation control should be derived
8613372Sgabeblack@google.com *  from this class. */
8713372Sgabeblack@google.comclass Module : public sc_core::sc_channel
8813372Sgabeblack@google.com{
8913372Sgabeblack@google.com  protected:
9013372Sgabeblack@google.com    /** Event to trigger (via. ::notify) for event scheduling from
9113372Sgabeblack@google.com     *  outside gem5 */
9213372Sgabeblack@google.com    sc_core::sc_event externalSchedulingEvent;
9313372Sgabeblack@google.com
9413372Sgabeblack@google.com    /** Event to trigger on exit of eventLoop */
9513372Sgabeblack@google.com    sc_core::sc_event eventLoopExitEvent;
9613372Sgabeblack@google.com
9713372Sgabeblack@google.com    /** Event to trigger to enter eventLoop */
9813372Sgabeblack@google.com    sc_core::sc_event eventLoopEnterEvent;
9913372Sgabeblack@google.com
10013372Sgabeblack@google.com    /** Expected exit time of last eventLoop sleep */
10113372Sgabeblack@google.com    Tick wait_exit_time;
10213372Sgabeblack@google.com
10313372Sgabeblack@google.com    /** Are we in Module::simulate?  Used to mask events when not inside
10413372Sgabeblack@google.com     *  the simulate loop */
10513372Sgabeblack@google.com    bool in_simulate;
10613372Sgabeblack@google.com
10713372Sgabeblack@google.com    /** Placeholder base class for a variant event queue if this becomes
10813372Sgabeblack@google.com     *  useful */
10913372Sgabeblack@google.com    class SCEventQueue : public EventQueue
11013372Sgabeblack@google.com    {
11113372Sgabeblack@google.com      protected:
11213372Sgabeblack@google.com        Module &module;
11313372Sgabeblack@google.com
11413372Sgabeblack@google.com      public:
11513372Sgabeblack@google.com        SCEventQueue(const std::string &name,
11613372Sgabeblack@google.com            Module &module_) : EventQueue(name), module(module_)
11713372Sgabeblack@google.com        { }
11813372Sgabeblack@google.com
11913372Sgabeblack@google.com        /** Signal module to wakeup */
12013372Sgabeblack@google.com        void wakeup(Tick when);
12113372Sgabeblack@google.com    };
12213372Sgabeblack@google.com
12313372Sgabeblack@google.com    /** Service any async event marked up in the globals event_... */
12413372Sgabeblack@google.com    void serviceAsyncEvent();
12513372Sgabeblack@google.com
12613372Sgabeblack@google.com  public:
12713372Sgabeblack@google.com    /** Simulate is a process */
12813372Sgabeblack@google.com    SC_HAS_PROCESS(Module);
12913372Sgabeblack@google.com
13013372Sgabeblack@google.com    Module(sc_core::sc_module_name name);
13113372Sgabeblack@google.com
13213372Sgabeblack@google.com    /** Last exitEvent from eventLoop */
13313372Sgabeblack@google.com    Event *exitEvent;
13413372Sgabeblack@google.com
13513372Sgabeblack@google.com    /** Setup global event queues.  Call this before any other event queues
13613372Sgabeblack@google.com     *  are created */
13713372Sgabeblack@google.com    static void setupEventQueues(Module &module);
13813372Sgabeblack@google.com
13913372Sgabeblack@google.com    /** Catch gem5 time up with SystemC */
14013372Sgabeblack@google.com    void catchup();
14113372Sgabeblack@google.com
14213372Sgabeblack@google.com    /** Notify an externalSchedulingEvent at the given time from the
14313372Sgabeblack@google.com     *  current SystemC time */
14413372Sgabeblack@google.com    void notify(sc_core::sc_time time_from_now = sc_core::SC_ZERO_TIME);
14513372Sgabeblack@google.com
14613372Sgabeblack@google.com    /** Process an event triggered by externalSchedulingEvent and also
14713372Sgabeblack@google.com     *  call eventLoop (to try and mop up any events at this time) if there
14813372Sgabeblack@google.com     *  are any scheduled events */
14913372Sgabeblack@google.com    void serviceExternalEvent();
15013372Sgabeblack@google.com
15113372Sgabeblack@google.com    /** Process gem5 events up until an exit event or there are no events
15213372Sgabeblack@google.com     *  left. */
15313372Sgabeblack@google.com    void eventLoop();
15413372Sgabeblack@google.com
15513372Sgabeblack@google.com    /** Run eventLoop up to num_cycles and return the final event */
15613372Sgabeblack@google.com    GlobalSimLoopExitEvent *simulate(Tick num_cycles = MaxTick);
15713372Sgabeblack@google.com};
15813372Sgabeblack@google.com
15913372Sgabeblack@google.com/** There are assumptions throughout Gem5SystemC file that a tick is 1ps.
16013372Sgabeblack@google.com *  Make this the case */
16113372Sgabeblack@google.comvoid setTickFrequency();
16213372Sgabeblack@google.com
16313372Sgabeblack@google.com}
16413372Sgabeblack@google.com
16513372Sgabeblack@google.com#endif // __SIM_SC_MODULE_HH__
166