📄 tlm_gp.h
字号:
/***************************************************************************** The following code is derived, directly or indirectly, from the SystemC source code Copyright (c) 1996-2008 by all Contributors. All Rights reserved. The contents of this file are subject to the restrictions and limitations set forth in the SystemC Open Source License Version 3.0 (the "License"); You may not use this file except in compliance with such restrictions and limitations. You may obtain instructions on how to receive a copy of the License at http://www.systemc.org/. Software distributed by Contributors under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License.*****************************************************************************/#ifndef __TLM_GP_H__#define __TLM_GP_H__#include <systemc>#include "tlm_array.h"namespace tlm {classtlm_generic_payload;class tlm_mm_interface {public: virtual void free(tlm_generic_payload*) = 0; virtual ~tlm_mm_interface() {}};//---------------------------------------------------------------------------// Classes and helper functions for the extension mechanism//---------------------------------------------------------------------------// Helper function:inline unsigned int max_num_extensions(bool increment=false){ static unsigned int max_num = 0; if (increment) ++max_num; return max_num;}// This class can be used for storing pointers to the extension classes, used// in tlm_generic_payload:class tlm_extension_base{public: virtual tlm_extension_base* clone() const = 0; virtual void free() { delete this; } virtual void copy_from(tlm_extension_base const &) = 0;protected: virtual ~tlm_extension_base() {} static unsigned int register_extension() { return (max_num_extensions(true) - 1); };};// Base class for all extension classes, derive your extension class in// the following way:// class my_extension : public tlm_extension<my_extension> { ...// This triggers proper extension registration during C++ static// contruction time. my_extension::ID will hold the unique index in the// tlm_generic_payload::m_extensions array.template <typename T>class tlm_extension : public tlm_extension_base{public: virtual tlm_extension_base* clone() const = 0; virtual void copy_from(tlm_extension_base const &ext) = 0; //{assert(typeid(this)==typeid(ext)); assert(ID === ext.ID); assert(0);} virtual ~tlm_extension() {} const static unsigned int ID;};template <typename T>constunsigned int tlm_extension<T>::ID = tlm_extension_base::register_extension();//---------------------------------------------------------------------------// enumeration types//---------------------------------------------------------------------------enum tlm_command { TLM_READ_COMMAND, TLM_WRITE_COMMAND, TLM_IGNORE_COMMAND};enum tlm_response_status { TLM_OK_RESPONSE = 1, TLM_INCOMPLETE_RESPONSE = 0, TLM_GENERIC_ERROR_RESPONSE = -1, TLM_ADDRESS_ERROR_RESPONSE = -2, TLM_COMMAND_ERROR_RESPONSE = -3, TLM_BURST_ERROR_RESPONSE = -4, TLM_BYTE_ENABLE_ERROR_RESPONSE = -5};#define TLM_BYTE_DISABLED 0x0#define TLM_BYTE_ENABLED 0xff//---------------------------------------------------------------------------// The generic payload class://---------------------------------------------------------------------------class tlm_generic_payload {public: //--------------- // Constructors //--------------- // Default constructor tlm_generic_payload() : m_address(0) , m_command(TLM_IGNORE_COMMAND) , m_data(0) , m_length(0) , m_response_status(TLM_INCOMPLETE_RESPONSE) , m_dmi(false) , m_byte_enable(0) , m_byte_enable_length(0) , m_streaming_width(0) , m_extensions(max_num_extensions()) , m_mm(0) , m_ref_count(0) { } explicit tlm_generic_payload(tlm_mm_interface* mm) : m_address(0) , m_command(TLM_IGNORE_COMMAND) , m_data(0) , m_length(0) , m_response_status(TLM_INCOMPLETE_RESPONSE) , m_dmi(false) , m_byte_enable(0) , m_byte_enable_length(0) , m_streaming_width(0) , m_extensions(max_num_extensions()) , m_mm(mm) , m_ref_count(0) { } void acquire(){assert(m_mm != 0); m_ref_count++;} void release(){assert(m_mm != 0); if (--m_ref_count==0) m_mm->free(this);} int get_ref_count(){return m_ref_count;} void set_mm(tlm_mm_interface* mm) { m_mm = mm; } bool has_mm() { return m_mm != 0; } void reset(){ //should the other members be reset too? m_extensions.free_entire_cache(); };private: //disabled copy ctor and assignment operator. // Copy constructor tlm_generic_payload(const tlm_generic_payload& x) : m_address(x.get_address()) , m_command(x.get_command()) , m_data(x.get_data_ptr()) , m_length(x.get_data_length()) , m_response_status(x.get_response_status()) , m_dmi(x.is_dmi_allowed()) , m_byte_enable(x.get_byte_enable_ptr()) , m_byte_enable_length(x.get_byte_enable_length()) , m_streaming_width(x.get_streaming_width()) , m_extensions(max_num_extensions()) { // copy all extensions for(unsigned int i=0; i<m_extensions.size(); i++) { m_extensions[i] = x.get_extension(i); } } // Assignment operator tlm_generic_payload& operator= (const tlm_generic_payload& x) { m_command = x.get_command(); m_address = x.get_address(); m_data = x.get_data_ptr(); m_length = x.get_data_length(); m_response_status = x.get_response_status(); m_byte_enable = x.get_byte_enable_ptr(); m_byte_enable_length = x.get_byte_enable_length(); m_streaming_width = x.get_streaming_width(); m_dmi = x.is_dmi_allowed(); // extension copy: all extension arrays must be of equal size by // construction (i.e. it must either be constructed after C++ // static construction time, or the resize_extensions() method must // have been called prior to using the object) for(unsigned int i=0; i<m_extensions.size(); i++) { m_extensions[i] = x.get_extension(i); } return (*this); }public: // non-virtual deep-copying of the object void deep_copy_from(const tlm_generic_payload & other) { m_command = other.get_command(); m_address = other.get_address(); m_length = other.get_data_length(); m_response_status = other.get_response_status(); m_byte_enable_length = other.get_byte_enable_length(); m_streaming_width = other.get_streaming_width(); m_dmi = other.is_dmi_allowed(); // deep copy data // there must be enough space in the target transaction! if(m_data && other.m_data) { memcpy(m_data, other.m_data, m_length); } // deep copy byte enables // there must be enough space in the target transaction! if(m_byte_enable && other.m_byte_enable) { memcpy(m_byte_enable, other.m_byte_enable, m_byte_enable_length); } // deep copy extensions (sticky and non-sticky) for(unsigned int i=0; i<other.m_extensions.size(); i++) { if(other.m_extensions[i]) { //original has extension i if(!m_extensions[i]) { //We don't: clone. tlm_extension_base *ext = other.m_extensions[i]->clone(); if(ext) //extension may not be clonable. { if(has_mm()) { //mm can take care of removing cloned extensions set_auto_extension(i, ext); } else { // no mm, user will call free_all_extensions(). set_extension(i, ext); } } } else { //We already have such extension. Copy original over it. m_extensions[i]->copy_from(*other.m_extensions[i]); } } } } void update_extensions_from(const tlm_generic_payload & other) { // deep copy extensions that are already present for(unsigned int i=0; i<other.m_extensions.size(); i++) { if(other.m_extensions[i]) { //original has extension i if(m_extensions[i]) { //We have it too. copy. m_extensions[i]->copy_from(*other.m_extensions[i]); } } } } // Free all extensions. Useful when reusing a cloned transaction that doesn't have memory manager. // normal and sticky extensions are freed and extension array cleared. void free_all_extensions() { m_extensions.free_entire_cache(); for(unsigned int i=0; i<m_extensions.size(); i++) { if(m_extensions[i]) { m_extensions[i]->free();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -