TLM-2.0: include/tlm/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo.h Source File

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# include/tlm/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo.h

Go to the documentation of this file.

    00001 /*****************************************************************************
    00002
    00003   The following code is derived, directly or indirectly, from the SystemC
    00004   source code Copyright (c) 1996-2008 by all Contributors.
    00005   All Rights reserved.
    00006
    00007   The contents of this file are subject to the restrictions and limitations
    00008   set forth in the SystemC Open Source License Version 3.0 (the "License");
    00009   You may not use this file except in compliance with such restrictions and
    00010   limitations. You may obtain instructions on how to receive a copy of the
    00011   License at http://www.systemc.org/. Software distributed by Contributors
    00012   under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
    00013   ANY KIND, either express or implied. See the License for the specific
    00014   language governing rights and limitations under the License.
    00015
    00016  *****************************************************************************/
    00017
    00018 #ifndef __TLM_FIFO_H__
    00019 #define __TLM_FIFO_H__
    00020
    00021 //
    00022 // This implements put, get and peek
    00023 //
    00024 // It also implements 0 and infinite size fifos - but the size
    00025 // zero fifos aren't rendezvous like zero length fifos, they simply are both
    00026 // full and empty at the same time.
    00027 //
    00028 // The size can be dynamically changed using the resize interface
    00029 //
    00030 // To get an infinite fifo use a -ve size in the constructor.
    00031 // The absolute value of the size is taken as the starting size of the
    00032 // actual physical buffer.
    00033 //
    00034
    00035 //#include <systemc>
    00036
    00037 #include "tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_fifo_ifs.h"
    00038 #include "tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/circular_buffer.h"
    00039
    00040 namespace tlm {
    00041
    00042 template <typename T>
    00043 class tlm_fifo :
    00044   public virtual tlm_fifo_get_if<T>,
    00045   public virtual tlm_fifo_put_if<T>,
    00046   public sc_core::sc_prim_channel
    00047 {
    00048 public:
    00049
    00050     // constructors
    00051
    00052     explicit tlm_fifo( int size_ = 1 )
    00053       : sc_core::sc_prim_channel( sc_core::sc_gen_unique_name( "fifo" ) ) {
    00054
    00055       init( size_ );
    00056
    00057     }
    00058
    00059     explicit tlm_fifo( const char* name_, int size_ = 1 )
    00060       : sc_core::sc_prim_channel( name_ ) {
    00061
    00062       init( size_ );
    00063
    00064     }
    00065
    00066     // destructor
    00067
    00068     virtual ~tlm_fifo() {
    00069
    00070       if( buffer != 0 ) delete buffer;
    00071
    00072     }
    00073
    00074     // tlm get interface
    00075
    00076     T get( tlm_tag<T> *t = 0 );
    00077
    00078     bool nb_get( T& );
    00079     bool nb_can_get( tlm_tag<T> *t = 0 ) const;
    00080     const sc_core::sc_event &ok_to_get( tlm_tag<T> *t = 0 ) const {
    00081       return m_data_written_event;
    00082     }
    00083
    00084     // tlm peek interface
    00085
    00086     T peek( tlm_tag<T> *t = 0 ) const;
    00087
    00088     bool nb_peek( T& ) const;
    00089     bool nb_can_peek( tlm_tag<T> *t = 0 ) const;
    00090     const sc_core::sc_event &ok_to_peek( tlm_tag<T> *t = 0 ) const {
    00091       return m_data_written_event;
    00092     }
    00093
    00094     // tlm put interface
    00095
    00096     void put( const T& );
    00097
    00098     bool nb_put( const T& );
    00099     bool nb_can_put( tlm_tag<T> *t = 0 ) const;
    00100
    00101     const sc_core::sc_event& ok_to_put( tlm_tag<T> *t = 0 ) const {
    00102       return m_data_read_event;
    00103     }
    00104
    00105     // resize if
    00106
    00107     void nb_expand( unsigned int n = 1 );
    00108     void nb_unbound( unsigned int n = 16 );
    00109
    00110     bool nb_reduce( unsigned int n = 1 );
    00111     bool nb_bound( unsigned int n );
    00112
    00113     // debug interface
    00114
    00115     bool nb_peek( T & , int n ) const;
    00116     bool nb_poke( const T & , int n = 0 );
    00117
    00118     int used() const {
    00119       return m_num_readable - m_num_read;
    00120     }
    00121
    00122     int size() const {
    00123       return m_size;
    00124     }
    00125
    00126     void debug() const {
    00127
    00128       if( is_empty() ) std::cout << "empty" << std::endl;
    00129       if( is_full() ) std::cout << "full" << std::endl;
    00130
    00131       std::cout << "size " << size() << " - " << used() << " used "
    00132                 << std::endl;
    00133       std::cout << "readable " << m_num_readable
    00134                 << std::endl;
    00135       std::cout << "written/read " << m_num_written << "/" << m_num_read
    00136                 << std::endl;
    00137
    00138     }
    00139
    00140     // support functions
    00141
    00142     static const char* const kind_string;
    00143
    00144     const char* kind() const
    00145         { return kind_string; }
    00146
    00147
    00148 protected:
    00149     sc_core::sc_event &read_event( tlm_tag<T> *t = 0 ) {
    00150       return m_data_read_event;
    00151     }
    00152
    00153 protected:
    00154
    00155     void update();
    00156
    00157     // support methods
    00158
    00159     void init( int );
    00160
    00161 protected:
    00162
    00163     circular_buffer<T> *buffer;
    00164
    00165     int m_size;                  // logical size of fifo
    00166
    00167     int m_num_readable;          // #samples readable
    00168     int m_num_read;          // #samples read during this delta cycle
    00169     int m_num_written;           // #samples written during this delta cycle
    00170     bool m_expand;               // has an expand occurred during this delta cycle ?
    00171     int m_num_read_no_notify;    // #samples read without notify during this delta cycle
    00172
    00173     sc_core::sc_event m_data_read_event;
    00174     sc_core::sc_event m_data_written_event;
    00175
    00176 private:
    00177
    00178     // disabled
    00179     tlm_fifo( const tlm_fifo<T>& );
    00180     tlm_fifo& operator = ( const tlm_fifo<T>& );
    00181
    00182     //
    00183     // use nb_can_get() and nb_can_put() rather than the following two
    00184     // private functions
    00185     //
    00186
    00187     bool is_empty() const {
    00188       return used() == 0;
    00189     }
    00190
    00191     bool is_full() const {
    00192       return size() == m_num_readable + m_num_written;
    00193     }
    00194
    00195 };
    00196
    00197 template <typename T>
    00198 const char* const tlm_fifo<T>::kind_string = "tlm_fifo";
    00199
    00200
    00201 /******************************************************************
    00202 //
    00203 // init and update
    00204 //
    00205 ******************************************************************/
    00206
    00207 template< typename T >
    00208 inline
    00209 void
    00210 tlm_fifo<T>::init( int size_ ) {
    00211
    00212   if( size_ > 0 ) {
    00213     buffer = new circular_buffer<T>( size_);
    00214   }
    00215
    00216   else if( size_ < 0 ) {
    00217     buffer = new circular_buffer<T>( -size_ );
    00218   }
    00219
    00220   else {
    00221     buffer = new circular_buffer<T>( 16 );
    00222   }
    00223
    00224   m_size = size_;
    00225   m_num_readable = 0;
    00226   m_num_read = 0;
    00227   m_num_written = 0;
    00228   m_expand = false;
    00229   m_num_read_no_notify = false;
    00230
    00231 }
    00232
    00233 template < typename T>
    00234 inline
    00235 void
    00236 tlm_fifo<T>::update()
    00237 {
    00238     if( m_num_read > m_num_read_no_notify || m_expand ) {
    00239   m_data_read_event.notify( sc_core::SC_ZERO_TIME );
    00240     }
    00241
    00242     if( m_num_written > 0 ) {
    00243   m_data_written_event.notify( sc_core::SC_ZERO_TIME );
    00244     }
    00245
    00246     m_expand = false;
    00247     m_num_read = 0;
    00248     m_num_written = 0;
    00249     m_num_readable = buffer->used();
    00250     m_num_read_no_notify = 0;
    00251
    00252 }
    00253
    00254 } // namespace tlm
    00255
    00256 #include "tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_put_get.h"
    00257 #include "tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_peek.h"
    00258 #include "tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_resize.h"
    00259
    00260 #endif
    00261