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