summaryrefslogtreecommitdiff
path: root/src/systemc/ext/tlm_utils/peq_with_cb_and_phase.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/systemc/ext/tlm_utils/peq_with_cb_and_phase.h')
-rw-r--r--src/systemc/ext/tlm_utils/peq_with_cb_and_phase.h476
1 files changed, 237 insertions, 239 deletions
diff --git a/src/systemc/ext/tlm_utils/peq_with_cb_and_phase.h b/src/systemc/ext/tlm_utils/peq_with_cb_and_phase.h
index 60f96e6bd..e924aedce 100644
--- a/src/systemc/ext/tlm_utils/peq_with_cb_and_phase.h
+++ b/src/systemc/ext/tlm_utils/peq_with_cb_and_phase.h
@@ -17,128 +17,107 @@
*****************************************************************************/
-// 12-Jan-2009 John Aynsley Bug fix. Phase argument to notify should be const
-// 20-Mar-2009 John Aynsley Add cancel_all() method
+#ifndef __SYSTEMC_EXT_TLM_UTILS_PEQ_WITH_CB_AND_PHASE_H__
+#define __SYSTEMC_EXT_TLM_UTILS_PEQ_WITH_CB_AND_PHASE_H__
-
-#ifndef __PEQ_WITH_CB_AND_PHASE_H__
-#define __PEQ_WITH_CB_AND_PHASE_H__
-
-#ifndef SC_INCLUDE_DYNAMIC_PROCESSES // needed for sc_spawn
-# define SC_INCLUDE_DYNAMIC_PROCESSES
-#endif
-
-#include <vector>
#include <systemc>
#include <tlm>
+#include <vector>
-namespace tlm_utils {
+namespace tlm_utils
+{
template <typename PAYLOAD>
class time_ordered_list
{
-public:
- struct element
- {
- struct element *next;
- PAYLOAD p;
- sc_core::sc_time t;
- sc_dt::uint64 d;
- element(PAYLOAD& p, sc_core::sc_time t, sc_dt::uint64 d): p(p),t(t),d(d) {}
- element(){}
- };
-
- element *nill;
- element *empties;
- element *list;
- unsigned int size;
-
- time_ordered_list()
- : nill(new element()),
- empties(NULL),
- list(nill),
- size(0)
- {
- }
-
- ~time_ordered_list() {
- reset();
- while(empties){
- struct element *e=empties->next;
- delete empties;
- empties=e;
- }
- delete nill;
- }
+ public:
+ struct element
+ {
+ struct element *next;
+ PAYLOAD p;
+ sc_core::sc_time t;
+ sc_dt::uint64 d;
+ element(PAYLOAD &p, sc_core::sc_time t, sc_dt::uint64 d) :
+ p(p), t(t), d(d)
+ {}
+ element() {}
+ };
+
+ element *nill;
+ element *empties;
+ element *list;
+ unsigned int size;
- void reset() {
- while(size) {
- delete_top();
+ time_ordered_list() : nill(new element()), empties(NULL),
+ list(nill), size(0)
+ {}
+
+ ~time_ordered_list()
+ {
+ reset();
+ while (empties) {
+ struct element *e = empties->next;
+ delete empties;
+ empties = e;
+ }
+ delete nill;
}
- }
- void insert(const PAYLOAD& p, sc_core::sc_time t) {
- if (!empties) {
- empties=new struct element();
- empties->next=NULL;
+ void
+ reset()
+ {
+ while (size) {
+ delete_top();
+ }
}
- struct element *e=empties;
- empties=empties->next;
- e->p=p;
- e->t=t;
- e->d=sc_core::sc_delta_count();
-
- struct element * ancestor=nill;
- struct element * iterator=list;
- while (iterator!=nill && iterator->t<=t){
- ancestor=iterator;
- iterator=iterator->next;
- }
- if (ancestor==nill){
- e->next=list;
- list=e;
+ void
+ insert(const PAYLOAD &p, sc_core::sc_time t)
+ {
+ if (!empties) {
+ empties = new struct element();
+ empties->next=NULL;
+ }
+
+ struct element *e = empties;
+ empties = empties->next;
+ e->p = p;
+ e->t = t;
+ e->d = sc_core::sc_delta_count();
+
+ struct element *ancestor = nill;
+ struct element *iterator = list;
+ while (iterator != nill && iterator->t <= t) {
+ ancestor = iterator;
+ iterator = iterator->next;
+ }
+ if (ancestor == nill) {
+ e->next = list;
+ list = e;
+ } else {
+ e->next = iterator;
+ ancestor->next = e;
+ }
+ size++;
}
- else {
- e->next=iterator;
- ancestor->next=e;
- }
- size++;
- }
-
- void delete_top(){
- if (list != nill) {
- struct element *e=list;
- list=list->next;
- e->next=empties;
- empties=e;
- size--;
+
+ void
+ delete_top()
+ {
+ if (list != nill) {
+ struct element *e = list;
+ list = list->next;
+ e->next = empties;
+ empties = e;
+ size--;
+ }
}
- }
-
- unsigned int get_size()
- {
- return size;
- }
-
- PAYLOAD &top()
- {
- return list->p;
- }
- sc_core::sc_time top_time()
- {
- return list->t;
- }
-
- sc_dt::uint64& top_delta()
- {
- return list->d;
- }
-
- sc_core::sc_time next_time()
- {
- return list->next->t;
- }
+
+ unsigned int get_size() { return size; }
+ PAYLOAD &top() { return list->p; }
+ sc_core::sc_time top_time() { return list->t; }
+ sc_dt::uint64 &top_delta() { return list->d; }
+ sc_core::sc_time next_time() { return list->next->t; }
};
//---------------------------------------------------------------------------
@@ -147,155 +126,174 @@ public:
* notifications. Each notification have an associate payload.
*/
//---------------------------------------------------------------------------
-template<typename OWNER,typename TYPES=tlm::tlm_base_protocol_types>
-class peq_with_cb_and_phase:
- public sc_core::sc_object
+template<typename OWNER, typename TYPES=tlm::tlm_base_protocol_types>
+class peq_with_cb_and_phase : public sc_core::sc_object
{
+ typedef typename TYPES::tlm_payload_type tlm_payload_type;
+ typedef typename TYPES::tlm_phase_type tlm_phase_type;
+ typedef std::pair<tlm_payload_type *, tlm_phase_type> PAYLOAD;
+ typedef void (OWNER::*cb)(tlm_payload_type &, const tlm_phase_type &);
+
+ class delta_list
+ {
+ public:
+ delta_list()
+ {
+ reset();
+ entries.resize(100);
+ }
+
+ inline void
+ insert(const PAYLOAD &p)
+ {
+ if (size==entries.size()) {
+ entries.resize(entries.size() * 2);
+ }
+ entries[size++] = p;
+ }
+
+ inline PAYLOAD &get() { return entries[out++]; }
+ inline bool next() { return out < size; }
+ inline void
+ reset()
+ {
+ size=0;
+ out=0;
+ }
+
+ public:
+ unsigned int size;
+
+ private:
+ std::vector<PAYLOAD> entries;
+ unsigned int out;
+ };
- typedef typename TYPES::tlm_payload_type tlm_payload_type;
- typedef typename TYPES::tlm_phase_type tlm_phase_type;
- typedef std::pair<tlm_payload_type*, tlm_phase_type> PAYLOAD;
- typedef void (OWNER::*cb)(tlm_payload_type&, const tlm_phase_type&);
-
- class delta_list{
public:
- delta_list(){
- reset();
- entries.resize(100);
+ peq_with_cb_and_phase(OWNER *_owner, cb _cb) :
+ sc_core::sc_object(sc_core::sc_gen_unique_name(
+ "peq_with_cb_and_phase")),
+ m_owner(_owner), m_cb(_cb)
+ {
+ sc_core::sc_spawn_options opts;
+ opts.spawn_method();
+ opts.set_sensitivity(&m_e);
+ opts.dont_initialize();
+ sc_core::sc_spawn(sc_bind(&peq_with_cb_and_phase::fec, this),
+ sc_core::sc_gen_unique_name("fec"), &opts);
}
- inline void insert(const PAYLOAD& p){
- if (size==entries.size()){
- entries.resize(entries.size()*2);
- }
- entries[size++]=p;
+ peq_with_cb_and_phase(const char *_name, OWNER *_owner, cb _cb) :
+ sc_core::sc_object(_name), m_owner(_owner), m_cb(_cb)
+ {
+ sc_core::sc_spawn_options opts;
+ opts.spawn_method();
+ opts.set_sensitivity(&m_e);
+ opts.dont_initialize();
+ sc_core::sc_spawn(sc_bind(&peq_with_cb_and_phase::fec, this),
+ sc_core::sc_gen_unique_name("fec"), &opts);
}
- inline PAYLOAD& get(){
- return entries[out++];
+ ~peq_with_cb_and_phase() {}
+
+ void
+ notify(tlm_payload_type &t, const tlm_phase_type &p,
+ const sc_core::sc_time &when)
+ {
+ if (when == sc_core::SC_ZERO_TIME) {
+ if (sc_core::sc_delta_count() & (sc_dt::uint64)0x1) {
+ // Uneven delta cycle so delta delay is for even cycle.
+ m_even_delta.insert(PAYLOAD(&t,p));
+ } else {
+ // Even delta cycle so delta delay is for uneven delta.
+ m_uneven_delta.insert(PAYLOAD(&t, p));
+ }
+ m_e.notify(sc_core::SC_ZERO_TIME);
+ } else {
+ m_ppq.insert(PAYLOAD(&t, p), when + sc_core::sc_time_stamp());
+ // Note, this will only overwrite the "newest" event.
+ m_e.notify(when);
+ }
}
- inline bool next(){
- return out<size;
+ void
+ notify(tlm_payload_type &t, const tlm_phase_type &p)
+ {
+ m_immediate_yield.insert(PAYLOAD(&t, p));
+ m_e.notify(); // Immediate notification.
}
- inline void reset(){
- size=0;
- out=0;
- }
- public:
- unsigned int size;
- private:
- std::vector<PAYLOAD> entries;
- unsigned int out;
- };
-
-public:
-
- peq_with_cb_and_phase(OWNER* _owner, cb _cb)
- :sc_core::sc_object( sc_core::sc_gen_unique_name( "peq_with_cb_and_phase" ) )
- ,m_owner(_owner)
- ,m_cb(_cb)
- {
- sc_core::sc_spawn_options opts;
- opts.spawn_method();
- opts.set_sensitivity(&m_e);
- opts.dont_initialize();
- sc_core::sc_spawn(sc_bind(&peq_with_cb_and_phase::fec, this),
- sc_core::sc_gen_unique_name("fec"), &opts);
- }
-
- peq_with_cb_and_phase(const char* _name, OWNER* _owner,cb _cb)
- : sc_core::sc_object( _name )
- ,m_owner(_owner)
- ,m_cb(_cb)
- {
- sc_core::sc_spawn_options opts;
- opts.spawn_method();
- opts.set_sensitivity(&m_e);
- opts.dont_initialize();
- sc_core::sc_spawn(sc_bind(&peq_with_cb_and_phase::fec, this),
- sc_core::sc_gen_unique_name("fec"), &opts);
- }
-
- ~peq_with_cb_and_phase(){}
-
- void notify (tlm_payload_type& t, const tlm_phase_type& p, const sc_core::sc_time& when){
- //t.aquire();
- if (when==sc_core::SC_ZERO_TIME) {
- if (sc_core::sc_delta_count() & (sc_dt::uint64)0x1) //uneven delta cycle so delta delay is for even cylce
- m_even_delta.insert(PAYLOAD(&t,p));
- else
- m_uneven_delta.insert(PAYLOAD(&t,p)); //even delta cycle so delta delay is for uneven delta
- m_e.notify(sc_core::SC_ZERO_TIME);
- }
- else {
- m_ppq.insert(PAYLOAD(&t,p), when + sc_core::sc_time_stamp() );
- m_e.notify(when); // note, this will only over-right the "newest" event.
+ // Cancel all events from the event queue.
+ void
+ cancel_all()
+ {
+ m_ppq.reset();
+ m_uneven_delta.reset();
+ m_even_delta.reset();
+ m_immediate_yield.reset();
+ m_e.cancel();
}
- }
-
- void notify (tlm_payload_type& t, const tlm_phase_type& p){
- m_immediate_yield.insert(PAYLOAD(&t,p));
- m_e.notify(); // immediate notification
- }
-
- // Cancel all events from the event queue
- void cancel_all() {
- m_ppq.reset();
- m_uneven_delta.reset();
- m_even_delta.reset();
- m_immediate_yield.reset();
- m_e.cancel();
- }
-
-private:
-
- void fec(){
- //immediate yield notifications
- while(m_immediate_yield.next()) {PAYLOAD& tmp=m_immediate_yield.get(); (m_owner->*m_cb)(*tmp.first, tmp.second);} //tmp.first->release();}
- m_immediate_yield.reset();
-
- //delta notifications
- if (sc_core::sc_delta_count() & (sc_dt::uint64) 0x1) {//uneven delta so put out all payloads for uneven delta
- while (m_uneven_delta.next()) {PAYLOAD& tmp=m_uneven_delta.get(); (m_owner->*m_cb)(*tmp.first, tmp.second);} //tmp.first->release();}
- m_uneven_delta.reset();
- if (m_even_delta.size) m_e.notify(sc_core::SC_ZERO_TIME);
- }
- else {
- while (m_even_delta.next()) {PAYLOAD& tmp=m_even_delta.get(); (m_owner->*m_cb)(*tmp.first, tmp.second);} //tmp.first->release();}
- m_even_delta.reset();
- if (m_uneven_delta.size) m_e.notify(sc_core::SC_ZERO_TIME);
- }
- if (!m_ppq.get_size()) return; //there were only delta notification
-
- //timed notifications
- const sc_core::sc_time now=sc_core::sc_time_stamp();
- sc_core::sc_time top=m_ppq.top_time();
- while(m_ppq.get_size() && top==now) { // push all active ones into target
- PAYLOAD& tmp=m_ppq.top();
- (m_owner->*m_cb)(*tmp.first, tmp.second); //tmp.first->release();}
- m_ppq.delete_top();
- top=m_ppq.top_time();
- }
- if ( m_ppq.get_size()) {
- m_e.notify( top - now) ;
+ private:
+ void
+ fec()
+ {
+ // Immediate yield notifications.
+ while (m_immediate_yield.next()) {
+ PAYLOAD &tmp = m_immediate_yield.get();
+ (m_owner->*m_cb)(*tmp.first, tmp.second);
+ }
+ m_immediate_yield.reset();
+
+ // Delta notifications.
+ if (sc_core::sc_delta_count() & (sc_dt::uint64)0x1) {
+ // Uneven delta so put out all payloads for uneven delta.
+ while (m_uneven_delta.next()) {
+ PAYLOAD &tmp = m_uneven_delta.get();
+ (m_owner->*m_cb)(*tmp.first, tmp.second);
+ }
+ m_uneven_delta.reset();
+ if (m_even_delta.size)
+ m_e.notify(sc_core::SC_ZERO_TIME);
+ } else {
+ while (m_even_delta.next()) {
+ PAYLOAD &tmp = m_even_delta.get();
+ (m_owner->*m_cb)(*tmp.first, tmp.second);
+ }
+ m_even_delta.reset();
+ if (m_uneven_delta.size)
+ m_e.notify(sc_core::SC_ZERO_TIME);
+ }
+ if (!m_ppq.get_size())
+ return; // There were only delta notification.
+
+ // Timed notifications.
+ const sc_core::sc_time now = sc_core::sc_time_stamp();
+ sc_core::sc_time top = m_ppq.top_time();
+
+ while (m_ppq.get_size() && top == now) {
+ // Push all active ones into target.
+ PAYLOAD &tmp = m_ppq.top();
+ (m_owner->*m_cb)(*tmp.first, tmp.second);
+ m_ppq.delete_top();
+ top = m_ppq.top_time();
+ }
+ if (m_ppq.get_size()) {
+ m_e.notify(top - now);
+ }
}
- }
-
- OWNER* m_owner;
- cb m_cb;
+ OWNER *m_owner;
+ cb m_cb;
- time_ordered_list<PAYLOAD> m_ppq;
- delta_list m_uneven_delta;
- delta_list m_even_delta;
- delta_list m_immediate_yield;
+ time_ordered_list<PAYLOAD> m_ppq;
+ delta_list m_uneven_delta;
+ delta_list m_even_delta;
+ delta_list m_immediate_yield;
- sc_core::sc_event m_e; // default event
+ sc_core::sc_event m_e; // Default event.
};
-}
+} // namespace tlm_utils
-#endif // __PEQ_WITH_CB_AND_PHASE_H__
+#endif /* __SYSTEMC_EXT_TLM_UTILS_PEQ_WITH_CB_AND_PHASE_H__ */