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