sensitivity.hh revision 13288:f1c04129f709
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#include "systemc/ext/core/sc_port.hh"
40
41namespace sc_core
42{
43
44class sc_event;
45class sc_event_and_list;
46class sc_event_or_list;
47class sc_event_finder;
48class sc_export_base;
49class sc_interface;
50class sc_port_base;
51
52} // namespace sc_core
53
54namespace sc_gem5
55{
56
57class Process;
58class Event;
59
60/*
61 * Common sensitivity interface.
62 */
63
64class Sensitivity
65{
66  protected:
67    Process *process;
68
69    Sensitivity(Process *p) : process(p) {}
70    virtual ~Sensitivity() {}
71
72    virtual void addToEvent(const ::sc_core::sc_event *e) = 0;
73    virtual void delFromEvent(const ::sc_core::sc_event *e) = 0;
74
75  public:
76    virtual void clear() = 0;
77
78    void satisfy();
79    virtual bool notify(Event *e);
80
81    enum Category
82    {
83        Static,
84        Dynamic
85    };
86
87    virtual Category category() = 0;
88
89    bool ofMethod();
90};
91
92
93/*
94 * Dynamic vs. static sensitivity.
95 */
96
97class DynamicSensitivity : virtual public Sensitivity
98{
99  protected:
100    DynamicSensitivity(Process *p) : Sensitivity(p) {}
101
102    void addToEvent(const ::sc_core::sc_event *e) override;
103    void delFromEvent(const ::sc_core::sc_event *e) override;
104
105  public:
106    Category category() override { return Dynamic; }
107};
108
109typedef std::vector<DynamicSensitivity *> DynamicSensitivities;
110
111
112class StaticSensitivity : virtual public Sensitivity
113{
114  protected:
115    StaticSensitivity(Process *p) : Sensitivity(p) {}
116
117    void addToEvent(const ::sc_core::sc_event *e) override;
118    void delFromEvent(const ::sc_core::sc_event *e) override;
119
120  public:
121    Category category() override { return Static; }
122};
123
124typedef std::vector<StaticSensitivity *> StaticSensitivities;
125
126
127/*
128 * Sensitivity to an event or events, which can be static or dynamic.
129 */
130
131class SensitivityEvent : virtual public Sensitivity
132{
133  protected:
134    const ::sc_core::sc_event *event;
135
136    SensitivityEvent(Process *p, const ::sc_core::sc_event *e=nullptr) :
137        Sensitivity(p), event(e)
138    {}
139
140  public:
141    void clear() override { delFromEvent(event); }
142};
143
144class SensitivityEvents : virtual public Sensitivity
145{
146  protected:
147    std::set<const ::sc_core::sc_event *> events;
148
149    SensitivityEvents(Process *p) : Sensitivity(p) {}
150    SensitivityEvents(
151            Process *p, const std::set<const ::sc_core::sc_event *> &s) :
152        Sensitivity(p), events(s)
153    {}
154
155  public:
156    void
157    clear() override
158    {
159        for (auto event: events)
160            delFromEvent(event);
161    }
162
163    void
164    addEvent(const ::sc_core::sc_event *event)
165    {
166        events.insert(event);
167        addToEvent(event);
168    }
169};
170
171
172/*
173 * Static sensitivities.
174 */
175
176void newStaticSensitivityEvent(Process *p, const sc_core::sc_event *e);
177void newStaticSensitivityInterface(Process *p, const sc_core::sc_interface *i);
178void newStaticSensitivityPort(Process *p, const sc_core::sc_port_base *pb);
179void newStaticSensitivityExport(
180        Process *p, const sc_core::sc_export_base *exp);
181void newStaticSensitivityFinder(
182        Process *p, const sc_core::sc_event_finder *f);
183
184
185class StaticSensitivityEvent :
186    public StaticSensitivity, public SensitivityEvent
187{
188    friend void newStaticSensitivityEvent(
189            Process *p, const sc_core::sc_event *e);
190
191  protected:
192    StaticSensitivityEvent(Process *p, const sc_core::sc_event *e) :
193        Sensitivity(p), StaticSensitivity(p), SensitivityEvent(p, e)
194    {}
195};
196
197class StaticSensitivityInterface :
198    public StaticSensitivity, public SensitivityEvent
199{
200    friend void newStaticSensitivityInterface(
201            Process *p, const sc_core::sc_interface *i);
202  protected:
203    StaticSensitivityInterface(Process *p, const sc_core::sc_interface *i);
204};
205
206class StaticSensitivityPort :
207    public StaticSensitivity, public SensitivityEvents
208{
209    friend void newStaticSensitivityPort(
210            Process *p, const sc_core::sc_port_base *pb);
211
212  protected:
213    StaticSensitivityPort(Process *p) :
214        Sensitivity(p), StaticSensitivity(p), SensitivityEvents(p)
215    {}
216};
217
218class StaticSensitivityExport :
219    public StaticSensitivity, public SensitivityEvent
220{
221  private:
222    friend void newStaticSensitivityExport(
223            Process *p, const sc_core::sc_export_base *exp);
224
225    StaticSensitivityExport(Process *p, const sc_core::sc_export_base *exp);
226};
227
228
229class StaticSensitivityFinder :
230    public StaticSensitivity, public SensitivityEvents
231{
232  private:
233    const sc_core::sc_event_finder *finder;
234
235    friend void newStaticSensitivityFinder(
236            Process *p, const sc_core::sc_event_finder *f);
237
238    StaticSensitivityFinder(Process *p, const sc_core::sc_event_finder *f) :
239        Sensitivity(p), StaticSensitivity(p), SensitivityEvents(p), finder(f)
240    {}
241
242  public:
243    const ::sc_core::sc_event &find(::sc_core::sc_interface *i);
244};
245
246
247/*
248 * Dynamic sensitivities.
249 */
250
251void newDynamicSensitivityEvent(Process *p, const sc_core::sc_event *e);
252void newDynamicSensitivityEventOrList(
253        Process *p, const sc_core::sc_event_or_list *eol);
254void newDynamicSensitivityEventAndList(
255        Process *p, const sc_core::sc_event_and_list *eal);
256
257class DynamicSensitivityEvent :
258    public DynamicSensitivity, public SensitivityEvent
259{
260  private:
261    friend void newDynamicSensitivityEvent(
262            Process *p, const sc_core::sc_event *e);
263
264    DynamicSensitivityEvent(Process *p, const sc_core::sc_event *e) :
265        Sensitivity(p), DynamicSensitivity(p), SensitivityEvent(p, e)
266    {}
267};
268
269class DynamicSensitivityEventOrList :
270    public DynamicSensitivity, public SensitivityEvents
271{
272  private:
273    friend void newDynamicSensitivityEventOrList(
274            Process *p, const sc_core::sc_event_or_list *eol);
275
276    DynamicSensitivityEventOrList(
277            Process *p, const sc_core::sc_event_or_list *eol);
278
279    bool notify(Event *e) override;
280};
281
282//XXX This sensitivity can't be reused. To reset it, it has to be deleted and
283//recreated. That works for dynamic sensitivities, but not for static.
284//Fortunately processes can't be statically sensitive to sc_event_and_lists.
285class DynamicSensitivityEventAndList :
286    public DynamicSensitivity, public SensitivityEvents
287{
288  private:
289    friend void newDynamicSensitivityEventAndList(
290            Process *p, const sc_core::sc_event_and_list *eal);
291
292    DynamicSensitivityEventAndList(
293            Process *p, const sc_core::sc_event_and_list *eal);
294
295    bool notify(Event *e) override;
296};
297
298} // namespace sc_gem5
299
300#endif  //__SYSTEMC_CORE_SENSITIVITY_HH__
301