sensitivity.hh revision 13262:ef4b783f84f7
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        Reset
86    };
87
88    virtual Category category() = 0;
89
90    bool ofMethod();
91};
92
93
94/*
95 * Dynamic vs. static vs. reset sensitivity.
96 */
97
98class DynamicSensitivity : virtual public Sensitivity
99{
100  protected:
101    DynamicSensitivity(Process *p) : Sensitivity(p) {}
102
103    void addToEvent(const ::sc_core::sc_event *e) override;
104    void delFromEvent(const ::sc_core::sc_event *e) override;
105
106  public:
107    Category category() override { return Dynamic; }
108};
109
110typedef std::vector<DynamicSensitivity *> DynamicSensitivities;
111
112
113class StaticSensitivity : virtual public Sensitivity
114{
115  protected:
116    StaticSensitivity(Process *p) : Sensitivity(p) {}
117
118    void addToEvent(const ::sc_core::sc_event *e) override;
119    void delFromEvent(const ::sc_core::sc_event *e) override;
120
121  public:
122    Category category() override { return Static; }
123};
124
125typedef std::vector<StaticSensitivity *> StaticSensitivities;
126
127class ResetSensitivity : virtual public Sensitivity
128{
129  private:
130    bool _val;
131    bool _sync;
132
133  protected:
134    ResetSensitivity(Process *p, bool _val, bool _sync) :
135        Sensitivity(p), _val(_val), _sync(_sync)
136    {}
137
138    void addToEvent(const ::sc_core::sc_event *e) override;
139    void delFromEvent(const ::sc_core::sc_event *e) override;
140
141    bool val() { return _val; }
142    bool sync() { return _sync; }
143
144  public:
145    Category category() override { return Reset; }
146};
147
148typedef std::vector<ResetSensitivity *> ResetSensitivities;
149
150
151/*
152 * Sensitivity to an event or events, which can be static or dynamic.
153 */
154
155class SensitivityEvent : virtual public Sensitivity
156{
157  protected:
158    const ::sc_core::sc_event *event;
159
160    SensitivityEvent(Process *p, const ::sc_core::sc_event *e=nullptr) :
161        Sensitivity(p), event(e)
162    {}
163
164  public:
165    void clear() override { delFromEvent(event); }
166};
167
168class SensitivityEvents : virtual public Sensitivity
169{
170  protected:
171    std::set<const ::sc_core::sc_event *> events;
172
173    SensitivityEvents(Process *p) : Sensitivity(p) {}
174    SensitivityEvents(
175            Process *p, const std::set<const ::sc_core::sc_event *> &s) :
176        Sensitivity(p), events(s)
177    {}
178
179  public:
180    void
181    clear() override
182    {
183        for (auto event: events)
184            delFromEvent(event);
185    }
186
187    void
188    addEvent(const ::sc_core::sc_event *event)
189    {
190        events.insert(event);
191        addToEvent(event);
192    }
193};
194
195
196/*
197 * Static sensitivities.
198 */
199
200void newStaticSensitivityEvent(Process *p, const sc_core::sc_event *e);
201void newStaticSensitivityInterface(Process *p, const sc_core::sc_interface *i);
202void newStaticSensitivityPort(Process *p, const sc_core::sc_port_base *pb);
203void newStaticSensitivityExport(
204        Process *p, const sc_core::sc_export_base *exp);
205void newStaticSensitivityFinder(
206        Process *p, const sc_core::sc_event_finder *f);
207
208
209class StaticSensitivityEvent :
210    public StaticSensitivity, public SensitivityEvent
211{
212    friend void newStaticSensitivityEvent(
213            Process *p, const sc_core::sc_event *e);
214
215  protected:
216    StaticSensitivityEvent(Process *p, const sc_core::sc_event *e) :
217        Sensitivity(p), StaticSensitivity(p), SensitivityEvent(p, e)
218    {}
219};
220
221class StaticSensitivityInterface :
222    public StaticSensitivity, public SensitivityEvent
223{
224    friend void newStaticSensitivityInterface(
225            Process *p, const sc_core::sc_interface *i);
226  protected:
227    StaticSensitivityInterface(Process *p, const sc_core::sc_interface *i);
228};
229
230class StaticSensitivityPort :
231    public StaticSensitivity, public SensitivityEvents
232{
233    friend void newStaticSensitivityPort(
234            Process *p, const sc_core::sc_port_base *pb);
235
236  protected:
237    StaticSensitivityPort(Process *p) :
238        Sensitivity(p), StaticSensitivity(p), SensitivityEvents(p)
239    {}
240};
241
242class StaticSensitivityExport :
243    public StaticSensitivity, public SensitivityEvent
244{
245  private:
246    friend void newStaticSensitivityExport(
247            Process *p, const sc_core::sc_export_base *exp);
248
249    StaticSensitivityExport(Process *p, const sc_core::sc_export_base *exp);
250};
251
252
253class StaticSensitivityFinder :
254    public StaticSensitivity, public SensitivityEvents
255{
256  private:
257    const sc_core::sc_event_finder *finder;
258
259    friend void newStaticSensitivityFinder(
260            Process *p, const sc_core::sc_event_finder *f);
261
262    StaticSensitivityFinder(Process *p, const sc_core::sc_event_finder *f) :
263        Sensitivity(p), StaticSensitivity(p), SensitivityEvents(p), finder(f)
264    {}
265
266  public:
267    const ::sc_core::sc_event &find(::sc_core::sc_interface *i);
268};
269
270
271/*
272 * Dynamic sensitivities.
273 */
274
275void newDynamicSensitivityEvent(Process *p, const sc_core::sc_event *e);
276void newDynamicSensitivityEventOrList(
277        Process *p, const sc_core::sc_event_or_list *eol);
278void newDynamicSensitivityEventAndList(
279        Process *p, const sc_core::sc_event_and_list *eal);
280
281class DynamicSensitivityEvent :
282    public DynamicSensitivity, public SensitivityEvent
283{
284  private:
285    friend void newDynamicSensitivityEvent(
286            Process *p, const sc_core::sc_event *e);
287
288    DynamicSensitivityEvent(Process *p, const sc_core::sc_event *e) :
289        Sensitivity(p), DynamicSensitivity(p), SensitivityEvent(p, e)
290    {}
291};
292
293class DynamicSensitivityEventOrList :
294    public DynamicSensitivity, public SensitivityEvents
295{
296  private:
297    friend void newDynamicSensitivityEventOrList(
298            Process *p, const sc_core::sc_event_or_list *eol);
299
300    DynamicSensitivityEventOrList(
301            Process *p, const sc_core::sc_event_or_list *eol);
302
303    bool notify(Event *e) override;
304};
305
306//XXX This sensitivity can't be reused. To reset it, it has to be deleted and
307//recreated. That works for dynamic sensitivities, but not for static.
308//Fortunately processes can't be statically sensitive to sc_event_and_lists.
309class DynamicSensitivityEventAndList :
310    public DynamicSensitivity, public SensitivityEvents
311{
312  private:
313    friend void newDynamicSensitivityEventAndList(
314            Process *p, const sc_core::sc_event_and_list *eal);
315
316    DynamicSensitivityEventAndList(
317            Process *p, const sc_core::sc_event_and_list *eal);
318
319    bool notify(Event *e) override;
320};
321
322/*
323 * Reset sensitivities.
324 */
325
326void newResetSensitivitySignal(
327        Process *p, const sc_core::sc_signal_in_if<bool> *signal,
328        bool val, bool sync);
329
330void newResetSensitivityPort(
331        Process *p, const sc_core::sc_in<bool> *port, bool val, bool sync);
332void newResetSensitivityPort(
333        Process *p, const sc_core::sc_inout<bool> *port, bool val, bool sync);
334void newResetSensitivityPort(
335        Process *p, const sc_core::sc_out<bool> *port, bool val, bool sync);
336
337class ResetSensitivitySignal :
338    public ResetSensitivity, public SensitivityEvent
339{
340  protected:
341    const sc_core::sc_signal_in_if<bool> *_signal;
342
343    friend void newResetSensitivitySignal(
344            Process *p, const sc_core::sc_signal_in_if<bool> *signal,
345            bool val, bool sync);
346
347    ResetSensitivitySignal(
348            Process *p, const sc_core::sc_signal_in_if<bool> *signal,
349            bool _val, bool _sync);
350
351    bool notify(Event *e) override;
352};
353
354class ResetSensitivityPort : public ResetSensitivitySignal
355{
356  private:
357    friend void newResetSensitivityPort(
358            Process *p, const sc_core::sc_in<bool> *port, bool val, bool sync);
359    friend void newResetSensitivityPort(
360            Process *p, const sc_core::sc_inout<bool> *port,
361            bool val, bool sync);
362    friend void newResetSensitivityPort(
363            Process *p, const sc_core::sc_out<bool> *port,
364            bool val, bool sync);
365
366    ResetSensitivityPort(
367            Process *p, const sc_core::sc_port_base *port,
368            bool _val, bool _sync) :
369        Sensitivity(p), ResetSensitivitySignal(p, nullptr, _val, _sync)
370    {}
371
372  public:
373    void setSignal(const ::sc_core::sc_signal_in_if<bool> *signal);
374};
375
376} // namespace sc_gem5
377
378#endif  //__SYSTEMC_CORE_SENSITIVITY_HH__
379