The Accellera implementation notifies all types of method sensitivities first, and then notifies all the ones for threads. Change-Id: I5eda75958675ba518f008852148030e032f70d83 Reviewed-on: https://gem5-review.googlesource.com/c/12807 Reviewed-by: Gabe Black <gabeblack@google.com> Maintainer: Gabe Black <gabeblack@google.com>
301 lines
7.9 KiB
C++
301 lines
7.9 KiB
C++
/*
|
|
* Copyright 2018 Google, Inc.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met: redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer;
|
|
* redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution;
|
|
* neither the name of the copyright holders nor the names of its
|
|
* contributors may be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
* Authors: Gabe Black
|
|
*/
|
|
|
|
#ifndef __SYSTEMC_CORE_SENSITIVITY_HH__
|
|
#define __SYSTEMC_CORE_SENSITIVITY_HH__
|
|
|
|
#include <set>
|
|
#include <vector>
|
|
|
|
#include "sim/eventq.hh"
|
|
#include "systemc/core/sched_event.hh"
|
|
#include "systemc/ext/core/sc_module.hh"
|
|
|
|
namespace sc_core
|
|
{
|
|
|
|
class sc_event;
|
|
class sc_event_and_list;
|
|
class sc_event_or_list;
|
|
class sc_event_finder;
|
|
class sc_export_base;
|
|
class sc_interface;
|
|
class sc_port_base;
|
|
|
|
} // namespace sc_core
|
|
|
|
namespace sc_gem5
|
|
{
|
|
|
|
class Process;
|
|
class Event;
|
|
|
|
/*
|
|
* Common sensitivity interface.
|
|
*/
|
|
|
|
class Sensitivity
|
|
{
|
|
protected:
|
|
Process *process;
|
|
|
|
Sensitivity(Process *p) : process(p) {}
|
|
virtual ~Sensitivity() {}
|
|
|
|
virtual void addToEvent(const ::sc_core::sc_event *e) = 0;
|
|
virtual void delFromEvent(const ::sc_core::sc_event *e) = 0;
|
|
|
|
virtual bool
|
|
notifyWork(Event *e)
|
|
{
|
|
satisfy();
|
|
return true;
|
|
}
|
|
|
|
public:
|
|
virtual void clear() = 0;
|
|
|
|
void satisfy();
|
|
bool notify(Event *e);
|
|
|
|
virtual bool dynamic() = 0;
|
|
|
|
bool ofMethod();
|
|
};
|
|
|
|
|
|
/*
|
|
* Dynamic vs. static sensitivity.
|
|
*/
|
|
|
|
class DynamicSensitivity : virtual public Sensitivity
|
|
{
|
|
protected:
|
|
DynamicSensitivity(Process *p) : Sensitivity(p) {}
|
|
|
|
void addToEvent(const ::sc_core::sc_event *e) override;
|
|
void delFromEvent(const ::sc_core::sc_event *e) override;
|
|
|
|
public:
|
|
bool dynamic() override { return true; }
|
|
};
|
|
|
|
typedef std::vector<DynamicSensitivity *> DynamicSensitivities;
|
|
|
|
|
|
class StaticSensitivity : virtual public Sensitivity
|
|
{
|
|
protected:
|
|
StaticSensitivity(Process *p) : Sensitivity(p) {}
|
|
|
|
void addToEvent(const ::sc_core::sc_event *e) override;
|
|
void delFromEvent(const ::sc_core::sc_event *e) override;
|
|
|
|
public:
|
|
bool dynamic() override { return false; }
|
|
};
|
|
|
|
typedef std::vector<StaticSensitivity *> StaticSensitivities;
|
|
|
|
|
|
/*
|
|
* Sensitivity to an event or events, which can be static or dynamic.
|
|
*/
|
|
|
|
class SensitivityEvent : virtual public Sensitivity
|
|
{
|
|
protected:
|
|
const ::sc_core::sc_event *event;
|
|
|
|
SensitivityEvent(Process *p, const ::sc_core::sc_event *e=nullptr) :
|
|
Sensitivity(p), event(e)
|
|
{}
|
|
|
|
public:
|
|
void clear() override { delFromEvent(event); }
|
|
};
|
|
|
|
class SensitivityEvents : virtual public Sensitivity
|
|
{
|
|
protected:
|
|
std::set<const ::sc_core::sc_event *> events;
|
|
|
|
SensitivityEvents(Process *p) : Sensitivity(p) {}
|
|
SensitivityEvents(
|
|
Process *p, const std::set<const ::sc_core::sc_event *> &s) :
|
|
Sensitivity(p), events(s)
|
|
{}
|
|
|
|
public:
|
|
void
|
|
clear() override
|
|
{
|
|
for (auto event: events)
|
|
delFromEvent(event);
|
|
}
|
|
|
|
void
|
|
addEvent(const ::sc_core::sc_event *event)
|
|
{
|
|
events.insert(event);
|
|
addToEvent(event);
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
* Static sensitivities.
|
|
*/
|
|
|
|
void newStaticSensitivityEvent(Process *p, const sc_core::sc_event *e);
|
|
void newStaticSensitivityInterface(Process *p, const sc_core::sc_interface *i);
|
|
void newStaticSensitivityPort(Process *p, const sc_core::sc_port_base *pb);
|
|
void newStaticSensitivityExport(
|
|
Process *p, const sc_core::sc_export_base *exp);
|
|
void newStaticSensitivityFinder(
|
|
Process *p, const sc_core::sc_event_finder *f);
|
|
|
|
|
|
class StaticSensitivityEvent :
|
|
public StaticSensitivity, public SensitivityEvent
|
|
{
|
|
friend void newStaticSensitivityEvent(
|
|
Process *p, const sc_core::sc_event *e);
|
|
|
|
protected:
|
|
StaticSensitivityEvent(Process *p, const sc_core::sc_event *e) :
|
|
Sensitivity(p), StaticSensitivity(p), SensitivityEvent(p, e)
|
|
{}
|
|
};
|
|
|
|
class StaticSensitivityInterface :
|
|
public StaticSensitivity, public SensitivityEvent
|
|
{
|
|
friend void newStaticSensitivityInterface(
|
|
Process *p, const sc_core::sc_interface *i);
|
|
protected:
|
|
StaticSensitivityInterface(Process *p, const sc_core::sc_interface *i);
|
|
};
|
|
|
|
class StaticSensitivityPort :
|
|
public StaticSensitivity, public SensitivityEvents
|
|
{
|
|
friend void newStaticSensitivityPort(
|
|
Process *p, const sc_core::sc_port_base *pb);
|
|
|
|
protected:
|
|
StaticSensitivityPort(Process *p) :
|
|
Sensitivity(p), StaticSensitivity(p), SensitivityEvents(p)
|
|
{}
|
|
};
|
|
|
|
class StaticSensitivityExport :
|
|
public StaticSensitivity, public SensitivityEvent
|
|
{
|
|
private:
|
|
friend void newStaticSensitivityExport(
|
|
Process *p, const sc_core::sc_export_base *exp);
|
|
|
|
StaticSensitivityExport(Process *p, const sc_core::sc_export_base *exp);
|
|
};
|
|
|
|
|
|
class StaticSensitivityFinder :
|
|
public StaticSensitivity, public SensitivityEvents
|
|
{
|
|
private:
|
|
const sc_core::sc_event_finder *finder;
|
|
|
|
friend void newStaticSensitivityFinder(
|
|
Process *p, const sc_core::sc_event_finder *f);
|
|
|
|
StaticSensitivityFinder(Process *p, const sc_core::sc_event_finder *f) :
|
|
Sensitivity(p), StaticSensitivity(p), SensitivityEvents(p), finder(f)
|
|
{}
|
|
|
|
public:
|
|
const ::sc_core::sc_event &find(::sc_core::sc_interface *i);
|
|
};
|
|
|
|
|
|
/*
|
|
* Dynamic sensitivities.
|
|
*/
|
|
|
|
void newDynamicSensitivityEvent(Process *p, const sc_core::sc_event *e);
|
|
void newDynamicSensitivityEventOrList(
|
|
Process *p, const sc_core::sc_event_or_list *eol);
|
|
void newDynamicSensitivityEventAndList(
|
|
Process *p, const sc_core::sc_event_and_list *eal);
|
|
|
|
class DynamicSensitivityEvent :
|
|
public DynamicSensitivity, public SensitivityEvent
|
|
{
|
|
private:
|
|
friend void newDynamicSensitivityEvent(
|
|
Process *p, const sc_core::sc_event *e);
|
|
|
|
DynamicSensitivityEvent(Process *p, const sc_core::sc_event *e) :
|
|
Sensitivity(p), DynamicSensitivity(p), SensitivityEvent(p, e)
|
|
{}
|
|
};
|
|
|
|
class DynamicSensitivityEventOrList :
|
|
public DynamicSensitivity, public SensitivityEvents
|
|
{
|
|
private:
|
|
friend void newDynamicSensitivityEventOrList(
|
|
Process *p, const sc_core::sc_event_or_list *eol);
|
|
|
|
DynamicSensitivityEventOrList(
|
|
Process *p, const sc_core::sc_event_or_list *eol);
|
|
|
|
bool notifyWork(Event *e) override;
|
|
};
|
|
|
|
//XXX This sensitivity can't be reused. To reset it, it has to be deleted and
|
|
//recreated. That works for dynamic sensitivities, but not for static.
|
|
//Fortunately processes can't be statically sensitive to sc_event_and_lists.
|
|
class DynamicSensitivityEventAndList :
|
|
public DynamicSensitivity, public SensitivityEvents
|
|
{
|
|
private:
|
|
friend void newDynamicSensitivityEventAndList(
|
|
Process *p, const sc_core::sc_event_and_list *eal);
|
|
|
|
DynamicSensitivityEventAndList(
|
|
Process *p, const sc_core::sc_event_and_list *eal);
|
|
|
|
bool notifyWork(Event *e) override;
|
|
};
|
|
|
|
} // namespace sc_gem5
|
|
|
|
#endif //__SYSTEMC_CORE_SENSITIVITY_HH__
|