sensitivity.hh revision 13206:c944ef4abb48
1/*
2 * Copyright 2018 Google, Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met: redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer;
8 * redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution;
11 * neither the name of the copyright holders nor the names of its
12 * contributors may be used to endorse or promote products derived from
13 * this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * Authors: Gabe Black
28 */
29
30#ifndef __SYSTEMC_CORE_SENSITIVITY_HH__
31#define __SYSTEMC_CORE_SENSITIVITY_HH__
32
33#include <set>
34#include <vector>
35
36#include "sim/eventq.hh"
37#include "systemc/core/sched_event.hh"
38#include "systemc/ext/core/sc_module.hh"
39
40namespace sc_core
41{
42
43class sc_event;
44class sc_event_and_list;
45class sc_event_or_list;
46class sc_event_finder;
47class sc_export_base;
48class sc_interface;
49class sc_port_base;
50
51} // namespace sc_core
52
53namespace sc_gem5
54{
55
56class Process;
57class Event;
58
59/*
60 * Common sensitivity interface.
61 */
62
63class Sensitivity
64{
65  protected:
66    Process *process;
67
68    Sensitivity(Process *p) : process(p) {}
69    virtual ~Sensitivity() {}
70
71    virtual void addToEvent(const ::sc_core::sc_event *e) = 0;
72    virtual void delFromEvent(const ::sc_core::sc_event *e) = 0;
73
74    virtual bool
75    notifyWork(Event *e)
76    {
77        satisfy();
78        return true;
79    }
80
81  public:
82    virtual void finalize() = 0;
83    virtual void clear() = 0;
84
85    void satisfy();
86    bool notify(Event *e);
87
88    virtual bool dynamic() = 0;
89};
90
91
92/*
93 * Dynamic vs. static sensitivity.
94 */
95
96class DynamicSensitivity : virtual public Sensitivity
97{
98  protected:
99    DynamicSensitivity(Process *p) : Sensitivity(p) {}
100
101    void addToEvent(const ::sc_core::sc_event *e) override;
102    void delFromEvent(const ::sc_core::sc_event *e) override;
103
104  public:
105    bool dynamic() override { return true; }
106};
107
108typedef std::vector<DynamicSensitivity *> DynamicSensitivities;
109
110
111class StaticSensitivity : virtual public Sensitivity
112{
113  protected:
114    StaticSensitivity(Process *p) : Sensitivity(p) {}
115
116    void addToEvent(const ::sc_core::sc_event *e) override;
117    void delFromEvent(const ::sc_core::sc_event *e) override;
118
119  public:
120    bool dynamic() override { return false; }
121};
122
123typedef std::vector<StaticSensitivity *> StaticSensitivities;
124
125
126/*
127 * Sensitivity to events, which can be static or dynamic.
128 */
129
130class SensitivityEvent : virtual public Sensitivity
131{
132  protected:
133    const ::sc_core::sc_event *event;
134
135    SensitivityEvent(Process *p, const ::sc_core::sc_event *e=nullptr) :
136        Sensitivity(p), event(e)
137    {}
138
139  public:
140    void finalize() override { addToEvent(event); }
141    void clear() override { delFromEvent(event); }
142};
143
144
145/*
146 * Static sensitivities.
147 */
148
149class StaticSensitivityEvent :
150    public StaticSensitivity, public SensitivityEvent
151{
152  public:
153    StaticSensitivityEvent(Process *p, const sc_core::sc_event *e) :
154        Sensitivity(p), StaticSensitivity(p), SensitivityEvent(p, e)
155    {}
156};
157
158class StaticSensitivityInterface :
159    public StaticSensitivity, public SensitivityEvent
160{
161  private:
162    const sc_core::sc_interface *interface;
163
164  public:
165    StaticSensitivityInterface(Process *p, const sc_core::sc_interface *i) :
166        Sensitivity(p), StaticSensitivity(p), SensitivityEvent(p), interface(i)
167    {}
168
169    void finalize() override;
170};
171
172class StaticSensitivityPort : public StaticSensitivity
173{
174  private:
175    const ::sc_core::sc_port_base *port;
176    std::set<const ::sc_core::sc_event *> events;
177
178  public:
179    StaticSensitivityPort(Process *p, const sc_core::sc_port_base *pb) :
180        Sensitivity(p), StaticSensitivity(p), port(pb)
181    {}
182
183    void finalize() override;
184
185    void
186    clear() override
187    {
188        for (auto event: events)
189            delFromEvent(event);
190    }
191};
192
193class StaticSensitivityExport :
194    public StaticSensitivity, public SensitivityEvent
195{
196  private:
197    const sc_core::sc_export_base *exp;
198
199  public:
200    StaticSensitivityExport(Process *p, const sc_core::sc_export_base *exp) :
201        Sensitivity(p), StaticSensitivity(p), SensitivityEvent(p), exp(exp)
202    {}
203
204    void finalize() override;
205};
206
207class StaticSensitivityFinder : public StaticSensitivity
208{
209  private:
210    const ::sc_core::sc_event_finder *finder;
211    std::set<const ::sc_core::sc_event *> events;
212
213  public:
214    StaticSensitivityFinder(Process *p, const sc_core::sc_event_finder *f) :
215        Sensitivity(p), StaticSensitivity(p), finder(f)
216    {}
217
218    void finalize() override;
219
220    void
221    clear() override
222    {
223        for (auto event: events)
224            delFromEvent(event);
225    }
226};
227
228
229/*
230 * Dynamic sensitivities.
231 */
232
233class DynamicSensitivityEvent :
234    public DynamicSensitivity, public SensitivityEvent
235{
236  public:
237    DynamicSensitivityEvent(Process *p, const sc_core::sc_event *e) :
238        Sensitivity(p), DynamicSensitivity(p), SensitivityEvent(p, e)
239    {}
240};
241
242class DynamicSensitivityEventOrList : public DynamicSensitivity
243{
244  private:
245    std::set<const ::sc_core::sc_event *> events;
246
247  protected:
248    bool notifyWork(Event *e) override;
249
250  public:
251    DynamicSensitivityEventOrList(
252            Process *p, const sc_core::sc_event_or_list *eol);
253
254    void finalize() override;
255    void clear() override;
256};
257
258//XXX This sensitivity can't be reused. To reset it, it has to be deleted and
259//recreated. That works for dynamic sensitivities, but not for static.
260//Fortunately processes can't be statically sensitive to sc_event_and_lists.
261class DynamicSensitivityEventAndList : public DynamicSensitivity
262{
263  private:
264    std::set<const ::sc_core::sc_event *> events;
265
266  protected:
267    bool notifyWork(Event *e) override;
268
269  public:
270    DynamicSensitivityEventAndList(
271            Process *p, const sc_core::sc_event_and_list *eal);
272
273    void finalize() override;
274    void clear() override;
275};
276
277} // namespace sc_gem5
278
279#endif  //__SYSTEMC_CORE_SENSITIVITY_HH__
280