113511Sgabeblack@google.com/*****************************************************************************
213511Sgabeblack@google.com
313511Sgabeblack@google.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
413511Sgabeblack@google.com  more contributor license agreements.  See the NOTICE file distributed
513511Sgabeblack@google.com  with this work for additional information regarding copyright ownership.
613511Sgabeblack@google.com  Accellera licenses this file to you under the Apache License, Version 2.0
713511Sgabeblack@google.com  (the "License"); you may not use this file except in compliance with the
813511Sgabeblack@google.com  License.  You may obtain a copy of the License at
913511Sgabeblack@google.com
1013511Sgabeblack@google.com    http://www.apache.org/licenses/LICENSE-2.0
1113511Sgabeblack@google.com
1213511Sgabeblack@google.com  Unless required by applicable law or agreed to in writing, software
1313511Sgabeblack@google.com  distributed under the License is distributed on an "AS IS" BASIS,
1413511Sgabeblack@google.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1513511Sgabeblack@google.com  implied.  See the License for the specific language governing
1613511Sgabeblack@google.com  permissions and limitations under the License.
1713511Sgabeblack@google.com
1813511Sgabeblack@google.com *****************************************************************************/
1913511Sgabeblack@google.com
2013511Sgabeblack@google.com// 12-Jan-2009  John Aynsley  Bug fix. sc_time argument to notify should be const
2113511Sgabeblack@google.com// 20-Mar-2009  John Aynsley  Add cancel_all() method
2213511Sgabeblack@google.com
2313511Sgabeblack@google.com
2413513Sgabeblack@google.com#ifndef __SYSTEMC_EXT_TLM_UTILS_PEQ_WITH_GET_H__
2513513Sgabeblack@google.com#define __SYSTEMC_EXT_TLM_UTILS_PEQ_WITH_GET_H__
2613511Sgabeblack@google.com
2713513Sgabeblack@google.com#include <map>
2813586Sgabeblack@google.com
2913586Sgabeblack@google.com#include "../core/sc_event.hh"
3013586Sgabeblack@google.com#include "../core/sc_main.hh"
3113586Sgabeblack@google.com#include "../core/sc_object.hh"
3213586Sgabeblack@google.com#include "../core/sc_time.hh"
3313511Sgabeblack@google.com
3413513Sgabeblack@google.comnamespace tlm_utils
3513513Sgabeblack@google.com{
3613511Sgabeblack@google.com
3713511Sgabeblack@google.comtemplate <class PAYLOAD>
3813511Sgabeblack@google.comclass peq_with_get : public sc_core::sc_object
3913511Sgabeblack@google.com{
4013513Sgabeblack@google.com  public:
4113513Sgabeblack@google.com    typedef PAYLOAD transaction_type;
4213513Sgabeblack@google.com    typedef std::pair<const sc_core::sc_time, transaction_type *> pair_type;
4313511Sgabeblack@google.com
4413513Sgabeblack@google.com  public:
4513513Sgabeblack@google.com    peq_with_get(const char *name) : sc_core::sc_object(name) {}
4613511Sgabeblack@google.com
4713513Sgabeblack@google.com    void
4813513Sgabeblack@google.com    notify(transaction_type &trans, const sc_core::sc_time &t)
4913513Sgabeblack@google.com    {
5013513Sgabeblack@google.com        m_scheduled_events.insert(pair_type(t + sc_core::sc_time_stamp(),
5113513Sgabeblack@google.com                    &trans));
5213513Sgabeblack@google.com        m_event.notify(t);
5313511Sgabeblack@google.com    }
5413511Sgabeblack@google.com
5513513Sgabeblack@google.com    void
5613513Sgabeblack@google.com    notify(transaction_type &trans)
5713513Sgabeblack@google.com    {
5813513Sgabeblack@google.com        m_scheduled_events.insert(pair_type(sc_core::sc_time_stamp(), &trans));
5913513Sgabeblack@google.com        m_event.notify(); // Immediate notification.
6013511Sgabeblack@google.com    }
6113511Sgabeblack@google.com
6213513Sgabeblack@google.com    // Needs to be called until it returns NULL
6313513Sgabeblack@google.com    transaction_type *
6413513Sgabeblack@google.com    get_next_transaction()
6513513Sgabeblack@google.com    {
6613513Sgabeblack@google.com        if (m_scheduled_events.empty()) {
6713513Sgabeblack@google.com            return nullptr;
6813513Sgabeblack@google.com        }
6913511Sgabeblack@google.com
7013513Sgabeblack@google.com        sc_core::sc_time now = sc_core::sc_time_stamp();
7113513Sgabeblack@google.com        if (m_scheduled_events.begin()->first <= now) {
7213513Sgabeblack@google.com            transaction_type *trans = m_scheduled_events.begin()->second;
7313513Sgabeblack@google.com            m_scheduled_events.erase(m_scheduled_events.begin());
7413513Sgabeblack@google.com            return trans;
7513513Sgabeblack@google.com        }
7613511Sgabeblack@google.com
7713513Sgabeblack@google.com        m_event.notify(m_scheduled_events.begin()->first - now);
7813511Sgabeblack@google.com
7913513Sgabeblack@google.com        return nullptr;
8013513Sgabeblack@google.com    }
8113511Sgabeblack@google.com
8213513Sgabeblack@google.com    sc_core::sc_event &get_event() { return m_event; }
8313513Sgabeblack@google.com
8413513Sgabeblack@google.com    // Cancel all events from the event queue.
8513513Sgabeblack@google.com    void
8613513Sgabeblack@google.com    cancel_all()
8713513Sgabeblack@google.com    {
8813513Sgabeblack@google.com        m_scheduled_events.clear();
8913513Sgabeblack@google.com        m_event.cancel();
9013513Sgabeblack@google.com    }
9113513Sgabeblack@google.com
9213513Sgabeblack@google.com  private:
9313513Sgabeblack@google.com    std::multimap<const sc_core::sc_time, transaction_type *>
9413513Sgabeblack@google.com        m_scheduled_events;
9513513Sgabeblack@google.com    sc_core::sc_event m_event;
9613511Sgabeblack@google.com};
9713511Sgabeblack@google.com
9813513Sgabeblack@google.com} // namespace tlm_utils
9913511Sgabeblack@google.com
10013513Sgabeblack@google.com#endif /* __SYSTEMC_EXT_TLM_UTILS_PEQ_WITH_GET_H__ */
101