1/*
2 * Copyright (c) 2014 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder.  You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2006 The Regents of The University of Michigan
15 * Copyright (c) 2013 Advanced Micro Devices, Inc.
16 * Copyright (c) 2013 Mark D. Hill and David A. Wood
17 * All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions are
21 * met: redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer;
23 * redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution;
26 * neither the name of the copyright holders nor the names of its
27 * contributors may be used to endorse or promote products derived from
28 * this software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 *
42 * Authors: Nathan Binkert
43 *          Steve Reinhardt
44 *          Andrew Bardsley
45 *          Christian Menard
46 */
47
48/**
49 * @file
50 *
51 * Defines an sc_module type to wrap a gem5 simulation.  The 'evaluate'
52 * thread on that module implements the gem5 event loop.
53 *
54 * This currently only supports a single event queue and strictly
55 * cooperatively threaded SystemC threads and so there should be at
56 * most one Gem5Module instantiated in any simulation.
57 */
58
59#ifndef __SIM_SC_MODULE_HH__
60#define __SIM_SC_MODULE_HH__
61
62#include <systemc>
63
64#include "sim/eventq.hh"
65#include "sim/sim_events.hh"
66
67namespace Gem5SystemC
68{
69
70/** A SystemC module implementing the gem5 event queue.  This object
71 *  doesn't actually own any of the simulation SimObjects (those need
72 *  to be administered separately) but it does control the event
73 *  queue.
74 *
75 *  The event loop here services gem5 events in order at the current time
76 *  and then yielding to another SystemC thread.  gem5 events are not
77 *  individually scheduled in SystemC.  For this reason, asynchronous events
78 *  and function interaction (for example TLM) with gem5 from SystemC must
79 *  notify the module so that the yielding 'wait' can be interrupted.
80 *  From the point of view of another SystemC module calling into gem5,
81 *  curTick can lag SystemC time, be exactly the same time but *never*
82 *  lead SystemC time.
83 *
84 *  This functionality is wrapped in an sc_module as its intended that
85 *  the a class representing top level simulation control should be derived
86 *  from this class. */
87class Module : public sc_core::sc_channel
88{
89  protected:
90    /** Event to trigger (via. ::notify) for event scheduling from
91     *  outside gem5 */
92    sc_core::sc_event externalSchedulingEvent;
93
94    /** Event to trigger on exit of eventLoop */
95    sc_core::sc_event eventLoopExitEvent;
96
97    /** Event to trigger to enter eventLoop */
98    sc_core::sc_event eventLoopEnterEvent;
99
100    /** Expected exit time of last eventLoop sleep */
101    Tick wait_exit_time;
102
103    /** Are we in Module::simulate?  Used to mask events when not inside
104     *  the simulate loop */
105    bool in_simulate;
106
107    /** Placeholder base class for a variant event queue if this becomes
108     *  useful */
109    class SCEventQueue : public EventQueue
110    {
111      protected:
112        Module &module;
113
114      public:
115        SCEventQueue(const std::string &name,
116            Module &module_) : EventQueue(name), module(module_)
117        { }
118
119        /** Signal module to wakeup */
120        void wakeup(Tick when);
121    };
122
123    /** Service any async event marked up in the globals event_... */
124    void serviceAsyncEvent();
125
126  public:
127    /** Simulate is a process */
128    SC_HAS_PROCESS(Module);
129
130    Module(sc_core::sc_module_name name);
131
132    /** Last exitEvent from eventLoop */
133    Event *exitEvent;
134
135    /** Setup global event queues.  Call this before any other event queues
136     *  are created */
137    static void setupEventQueues(Module &module);
138
139    /** Catch gem5 time up with SystemC */
140    void catchup();
141
142    /** Notify an externalSchedulingEvent at the given time from the
143     *  current SystemC time */
144    void notify(sc_core::sc_time time_from_now = sc_core::SC_ZERO_TIME);
145
146    /** Process an event triggered by externalSchedulingEvent and also
147     *  call eventLoop (to try and mop up any events at this time) if there
148     *  are any scheduled events */
149    void serviceExternalEvent();
150
151    /** Process gem5 events up until an exit event or there are no events
152     *  left. */
153    void eventLoop();
154
155    /** Run eventLoop up to num_cycles and return the final event */
156    GlobalSimLoopExitEvent *simulate(Tick num_cycles = MaxTick);
157};
158
159/** There are assumptions throughout Gem5SystemC file that a tick is 1ps.
160 *  Make this the case */
161void setTickFrequency();
162
163}
164
165#endif // __SIM_SC_MODULE_HH__
166