tlm_quantumkeeper.h revision 13586
17087Snate@binkert.org/***************************************************************************** 210959Sdavid.hashe@amd.com 37087Snate@binkert.org Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 47087Snate@binkert.org more contributor license agreements. See the NOTICE file distributed 57087Snate@binkert.org with this work for additional information regarding copyright ownership. 67087Snate@binkert.org Accellera licenses this file to you under the Apache License, Version 2.0 77087Snate@binkert.org (the "License"); you may not use this file except in compliance with the 87087Snate@binkert.org License. You may obtain a copy of the License at 97087Snate@binkert.org 107087Snate@binkert.org http://www.apache.org/licenses/LICENSE-2.0 117087Snate@binkert.org 127087Snate@binkert.org Unless required by applicable law or agreed to in writing, software 137087Snate@binkert.org distributed under the License is distributed on an "AS IS" BASIS, 145331Sgblack@eecs.umich.edu WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 155331Sgblack@eecs.umich.edu implied. See the License for the specific language governing 165331Sgblack@eecs.umich.edu permissions and limitations under the License. 175331Sgblack@eecs.umich.edu 185331Sgblack@eecs.umich.edu *****************************************************************************/ 195331Sgblack@eecs.umich.edu 205331Sgblack@eecs.umich.edu#ifndef __SYSTEMC_EXT_TLM_UTILS_TLM_QUANTUMKEEPER_H__ 215331Sgblack@eecs.umich.edu#define __SYSTEMC_EXT_TLM_UTILS_TLM_QUANTUMKEEPER_H__ 225331Sgblack@eecs.umich.edu 235331Sgblack@eecs.umich.edu#include "../core/sc_time.hh" 245331Sgblack@eecs.umich.edu 255331Sgblack@eecs.umich.edunamespace tlm_utils 265331Sgblack@eecs.umich.edu{ 275331Sgblack@eecs.umich.edu 285331Sgblack@eecs.umich.edu// tlm_quantumkeeper class 295331Sgblack@eecs.umich.edu// 305331Sgblack@eecs.umich.edu// The tlm_quantumkeeper class is used to keep track of the local time in 315331Sgblack@eecs.umich.edu// an initiator (how much it has run ahead of the SystemC time), to 325331Sgblack@eecs.umich.edu// synchronize with SystemC time etc. 335331Sgblack@eecs.umich.educlass tlm_quantumkeeper 345331Sgblack@eecs.umich.edu{ 355331Sgblack@eecs.umich.edu public: 365331Sgblack@eecs.umich.edu // 375331Sgblack@eecs.umich.edu // Static setters/getters for the global quantum value. 385331Sgblack@eecs.umich.edu // 395331Sgblack@eecs.umich.edu // The global quantum is the maximum time an initiator can run ahead of 405331Sgblack@eecs.umich.edu // SystemC time. All initiators will synchronize on timing points that are 415331Sgblack@eecs.umich.edu // multiples of the global quantum value. 424276Sgblack@eecs.umich.edu // 434276Sgblack@eecs.umich.edu static void 444276Sgblack@eecs.umich.edu set_global_quantum(const sc_core::sc_time &t) 454276Sgblack@eecs.umich.edu { 4610593Sgabeblack@google.com tlm::tlm_global_quantum::instance().set(t); 4710593Sgabeblack@google.com } 4810593Sgabeblack@google.com 4910593Sgabeblack@google.com static const sc_core::sc_time & 5010593Sgabeblack@google.com get_global_quantum() 5110593Sgabeblack@google.com { 5210593Sgabeblack@google.com return tlm::tlm_global_quantum::instance().get(); 5310593Sgabeblack@google.com } 5410593Sgabeblack@google.com 5510593Sgabeblack@google.com public: 5610593Sgabeblack@google.com tlm_quantumkeeper() : m_next_sync_point(sc_core::SC_ZERO_TIME), 5710593Sgabeblack@google.com m_local_time(sc_core::SC_ZERO_TIME) 5810593Sgabeblack@google.com {} 5910593Sgabeblack@google.com 6010593Sgabeblack@google.com virtual ~tlm_quantumkeeper() {} 6110593Sgabeblack@google.com 6210593Sgabeblack@google.com // Increment the local time (the time the initiator is ahead of the 6310593Sgabeblack@google.com // systemC time) After incrementing the local time an initiator should 6410593Sgabeblack@google.com // check (with the need_sync method) if a sync is required. 6510593Sgabeblack@google.com virtual void inc(const sc_core::sc_time &t) { m_local_time += t; } 6610593Sgabeblack@google.com 6710593Sgabeblack@google.com // Sets the local time (the time the initiator is ahead of the 6810593Sgabeblack@google.com // systemC time) After changing the local time an initiator should 6910593Sgabeblack@google.com // check (with the need_sync method) if a sync is required. 7010593Sgabeblack@google.com virtual void set(const sc_core::sc_time &t) { m_local_time = t; } 715238Sgblack@eecs.umich.edu 7210593Sgabeblack@google.com // Checks if a sync to systemC is required for this initiator. This will 7310593Sgabeblack@google.com // be the case if the local time becomes greater than the local (current) 7410593Sgabeblack@google.com // quantum value for this initiator. 7510593Sgabeblack@google.com virtual bool 7610593Sgabeblack@google.com need_sync() const 7710593Sgabeblack@google.com { 7810593Sgabeblack@google.com return sc_core::sc_time_stamp() + m_local_time >= m_next_sync_point; 7910593Sgabeblack@google.com } 8010593Sgabeblack@google.com 8110593Sgabeblack@google.com // Synchronize to systemC. This call will do a wait for the time the 8210593Sgabeblack@google.com // initiator was running ahead of systemC time and reset the 8310593Sgabeblack@google.com // tlm_quantumkeeper. 8410593Sgabeblack@google.com virtual void 8510593Sgabeblack@google.com sync() 8610593Sgabeblack@google.com { 8710593Sgabeblack@google.com sc_core::wait(m_local_time); 8810593Sgabeblack@google.com reset(); 896611Sgblack@eecs.umich.edu } 9010593Sgabeblack@google.com 9110593Sgabeblack@google.com // Non-virtual convenience method to set the local time and sync only if 9210593Sgabeblack@google.com // needed 9310593Sgabeblack@google.com void 9410593Sgabeblack@google.com set_and_sync(const sc_core::sc_time &t) 9510593Sgabeblack@google.com { 966611Sgblack@eecs.umich.edu set(t); 9710593Sgabeblack@google.com if (need_sync()) 9810593Sgabeblack@google.com sync(); 9910593Sgabeblack@google.com } 10010593Sgabeblack@google.com 10110593Sgabeblack@google.com // Resets the local time to SC_ZERO_TIME and computes the value of the 10210593Sgabeblack@google.com // next local quantum. This method should be called by an initiator after 10310593Sgabeblack@google.com // a wait because of a synchronization request by a target (TLM_ACCEPTED, 1046611Sgblack@eecs.umich.edu // or TLM_UPDATED). 1056611Sgblack@eecs.umich.edu virtual void 10610593Sgabeblack@google.com reset() 10710593Sgabeblack@google.com { 10810593Sgabeblack@google.com m_local_time = sc_core::SC_ZERO_TIME; 10910593Sgabeblack@google.com m_next_sync_point = sc_core::sc_time_stamp() + compute_local_quantum(); 11010593Sgabeblack@google.com } 11110593Sgabeblack@google.com 11210593Sgabeblack@google.com // Helper function to get the current systemC time, taken the local time 11310593Sgabeblack@google.com // into account. The current systemC time is calculated as the time 11410593Sgabeblack@google.com // returned by sc_time_stamp incremeneted with the time the initiator is 11510593Sgabeblack@google.com // running ahead. 11610593Sgabeblack@google.com virtual sc_core::sc_time 11710593Sgabeblack@google.com get_current_time() const 11810593Sgabeblack@google.com { 11910593Sgabeblack@google.com return sc_core::sc_time_stamp() + m_local_time; 12010593Sgabeblack@google.com } 12110593Sgabeblack@google.com 12210593Sgabeblack@google.com // Helper functions to get the time the initiator is running ahead of 12310593Sgabeblack@google.com // systenC (local time). This time should be passed to a target in the 12410593Sgabeblack@google.com // nb_transport call 1255292Sgblack@eecs.umich.edu virtual sc_core::sc_time 1266611Sgblack@eecs.umich.edu get_local_time() const 1275238Sgblack@eecs.umich.edu { 12810593Sgabeblack@google.com return m_local_time; 12910593Sgabeblack@google.com } 13010593Sgabeblack@google.com 13110593Sgabeblack@google.com protected: 13210593Sgabeblack@google.com // Calculate the next local quantum for this initiator. 13310593Sgabeblack@google.com // 13410593Sgabeblack@google.com // The method can be overloaded in a derived object if an initiator wants 13510593Sgabeblack@google.com // to use another local quantum. This derived object should also take the 13610593Sgabeblack@google.com // global quantum into account. It's local quantum should not be set to a 1375789Sgblack@eecs.umich.edu // value that is larger than the quantum returned by the 1385789Sgblack@eecs.umich.edu // compute_local_quantum of the tlm_global_quantum singleton. 13910593Sgabeblack@google.com virtual sc_core::sc_time 1405908Sgblack@eecs.umich.edu compute_local_quantum() 1414276Sgblack@eecs.umich.edu { 14210593Sgabeblack@google.com return tlm::tlm_global_quantum::instance().compute_local_quantum(); 14310593Sgabeblack@google.com } 14410593Sgabeblack@google.com 14510593Sgabeblack@google.com protected: 14610593Sgabeblack@google.com sc_core::sc_time m_next_sync_point; 14710593Sgabeblack@google.com sc_core::sc_time m_local_time; 14810593Sgabeblack@google.com}; 14910593Sgabeblack@google.com 15010593Sgabeblack@google.com} // namespace tlm_utils 15110593Sgabeblack@google.com 15210593Sgabeblack@google.com#endif /* __SYSTEMC_EXT_TLM_UTILS_TLM_QUANTUMKEEPER_H__ */ 15310593Sgabeblack@google.com