sensitivity.hh revision 13260
16145Snate@binkert.org/*
26145Snate@binkert.org * Copyright 2018 Google, Inc.
36145Snate@binkert.org *
46145Snate@binkert.org * Redistribution and use in source and binary forms, with or without
56145Snate@binkert.org * modification, are permitted provided that the following conditions are
66145Snate@binkert.org * met: redistributions of source code must retain the above copyright
76145Snate@binkert.org * notice, this list of conditions and the following disclaimer;
86145Snate@binkert.org * redistributions in binary form must reproduce the above copyright
96145Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
106145Snate@binkert.org * documentation and/or other materials provided with the distribution;
116145Snate@binkert.org * neither the name of the copyright holders nor the names of its
126145Snate@binkert.org * contributors may be used to endorse or promote products derived from
136145Snate@binkert.org * this software without specific prior written permission.
146145Snate@binkert.org *
156145Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
166145Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
176145Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
186145Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
196145Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
206145Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
216145Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
226145Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
236145Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
246145Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
256145Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
266145Snate@binkert.org *
276145Snate@binkert.org * Authors: Gabe Black
286145Snate@binkert.org */
296145Snate@binkert.org
306145Snate@binkert.org#ifndef __SYSTEMC_CORE_SENSITIVITY_HH__
316145Snate@binkert.org#define __SYSTEMC_CORE_SENSITIVITY_HH__
326145Snate@binkert.org
337002Snate@binkert.org#include <set>
347002Snate@binkert.org#include <vector>
357002Snate@binkert.org
366154Snate@binkert.org#include "sim/eventq.hh"
376285Snate@binkert.org#include "systemc/core/sched_event.hh"
386154Snate@binkert.org#include "systemc/ext/core/sc_module.hh"
396145Snate@binkert.org#include "systemc/ext/core/sc_port.hh"
406145Snate@binkert.org
416285Snate@binkert.orgnamespace sc_core
426145Snate@binkert.org{
436285Snate@binkert.org
446285Snate@binkert.orgclass sc_event;
456285Snate@binkert.orgclass sc_event_and_list;
466285Snate@binkert.orgclass sc_event_or_list;
476285Snate@binkert.orgclass sc_event_finder;
486285Snate@binkert.orgclass sc_export_base;
496145Snate@binkert.orgclass sc_interface;
506145Snate@binkert.orgclass sc_port_base;
516762SBrad.Beckmann@amd.com
526762SBrad.Beckmann@amd.com} // namespace sc_core
536762SBrad.Beckmann@amd.com
546762SBrad.Beckmann@amd.comnamespace sc_gem5
556762SBrad.Beckmann@amd.com{
566285Snate@binkert.org
576285Snate@binkert.orgclass Process;
586145Snate@binkert.orgclass Event;
596145Snate@binkert.org
606285Snate@binkert.org/*
616285Snate@binkert.org * Common sensitivity interface.
626145Snate@binkert.org */
636145Snate@binkert.org
646285Snate@binkert.orgclass Sensitivity
656145Snate@binkert.org{
666285Snate@binkert.org  protected:
676285Snate@binkert.org    Process *process;
686145Snate@binkert.org
697002Snate@binkert.org    Sensitivity(Process *p) : process(p) {}
706145Snate@binkert.org    virtual ~Sensitivity() {}
716145Snate@binkert.org
726285Snate@binkert.org    virtual void addToEvent(const ::sc_core::sc_event *e) = 0;
736145Snate@binkert.org    virtual void delFromEvent(const ::sc_core::sc_event *e) = 0;
746285Snate@binkert.org
756285Snate@binkert.org    virtual bool
766145Snate@binkert.org    notifyWork(Event *e)
776145Snate@binkert.org    {
786145Snate@binkert.org        satisfy();
797002Snate@binkert.org        return true;
806145Snate@binkert.org    }
816145Snate@binkert.org
826145Snate@binkert.org  public:
836285Snate@binkert.org    virtual void clear() = 0;
846285Snate@binkert.org
856285Snate@binkert.org    void satisfy();
866285Snate@binkert.org    bool notify(Event *e);
876285Snate@binkert.org
886971SBrad.Beckmann@amd.com    enum Category
896971SBrad.Beckmann@amd.com    {
906971SBrad.Beckmann@amd.com        Static,
916285Snate@binkert.org        Dynamic,
926285Snate@binkert.org        Reset
936285Snate@binkert.org    };
946285Snate@binkert.org
956285Snate@binkert.org    virtual Category category() = 0;
966285Snate@binkert.org
976285Snate@binkert.org    bool ofMethod();
986285Snate@binkert.org};
996285Snate@binkert.org
1006285Snate@binkert.org
1016285Snate@binkert.org/*
1026285Snate@binkert.org * Dynamic vs. static vs. reset sensitivity.
1036285Snate@binkert.org */
1046285Snate@binkert.org
1056285Snate@binkert.orgclass DynamicSensitivity : virtual public Sensitivity
1066285Snate@binkert.org{
1076285Snate@binkert.org  protected:
1086285Snate@binkert.org    DynamicSensitivity(Process *p) : Sensitivity(p) {}
1096285Snate@binkert.org
1106285Snate@binkert.org    void addToEvent(const ::sc_core::sc_event *e) override;
1116285Snate@binkert.org    void delFromEvent(const ::sc_core::sc_event *e) override;
1126285Snate@binkert.org
1136285Snate@binkert.org  public:
1146285Snate@binkert.org    Category category() override { return Dynamic; }
1156285Snate@binkert.org};
1167002Snate@binkert.org
1176285Snate@binkert.orgtypedef std::vector<DynamicSensitivity *> DynamicSensitivities;
1187002Snate@binkert.org
1197002Snate@binkert.org
1206285Snate@binkert.orgclass StaticSensitivity : virtual public Sensitivity
1216285Snate@binkert.org{
1226367Sdrh5@cs.wisc.edu  protected:
1236367Sdrh5@cs.wisc.edu    StaticSensitivity(Process *p) : Sensitivity(p) {}
1246631Spdudnik@gmail.com
1256285Snate@binkert.org    void addToEvent(const ::sc_core::sc_event *e) override;
1266285Snate@binkert.org    void delFromEvent(const ::sc_core::sc_event *e) override;
1276285Snate@binkert.org
1286285Snate@binkert.org  public:
1296285Snate@binkert.org    Category category() override { return Static; }
1306285Snate@binkert.org};
1316285Snate@binkert.org
1326285Snate@binkert.orgtypedef std::vector<StaticSensitivity *> StaticSensitivities;
1336285Snate@binkert.org
1346285Snate@binkert.orgclass ResetSensitivity : virtual public Sensitivity
1356285Snate@binkert.org{
1366285Snate@binkert.org  private:
1376285Snate@binkert.org    bool _val;
1386285Snate@binkert.org    bool _sync;
1396285Snate@binkert.org
1406285Snate@binkert.org  protected:
1416285Snate@binkert.org    ResetSensitivity(Process *p, bool _val, bool _sync) :
1426285Snate@binkert.org        Sensitivity(p), _val(_val), _sync(_sync)
1436285Snate@binkert.org    {}
1446285Snate@binkert.org
1456285Snate@binkert.org    void addToEvent(const ::sc_core::sc_event *e) override;
1466285Snate@binkert.org    void delFromEvent(const ::sc_core::sc_event *e) override;
1476285Snate@binkert.org
1486285Snate@binkert.org    bool val() { return _val; }
1496285Snate@binkert.org    bool sync() { return _sync; }
1506285Snate@binkert.org
1516285Snate@binkert.org  public:
1526285Snate@binkert.org    Category category() override { return Reset; }
1536285Snate@binkert.org};
1546285Snate@binkert.org
1556285Snate@binkert.orgtypedef std::vector<ResetSensitivity *> ResetSensitivities;
1566285Snate@binkert.org
1576285Snate@binkert.org
1586285Snate@binkert.org/*
1596285Snate@binkert.org * Sensitivity to an event or events, which can be static or dynamic.
1606145Snate@binkert.org */
1616145Snate@binkert.org
1626145Snate@binkert.orgclass SensitivityEvent : virtual public Sensitivity
1636145Snate@binkert.org{
1646145Snate@binkert.org  protected:
1657002Snate@binkert.org    const ::sc_core::sc_event *event;
1666145Snate@binkert.org
1676145Snate@binkert.org    SensitivityEvent(Process *p, const ::sc_core::sc_event *e=nullptr) :
1687002Snate@binkert.org        Sensitivity(p), event(e)
1696145Snate@binkert.org    {}
1706145Snate@binkert.org
1716145Snate@binkert.org  public:
1726145Snate@binkert.org    void clear() override { delFromEvent(event); }
1736145Snate@binkert.org};
1746145Snate@binkert.org
1756145Snate@binkert.orgclass SensitivityEvents : virtual public Sensitivity
1766145Snate@binkert.org{
1776145Snate@binkert.org  protected:
1786145Snate@binkert.org    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