C:/ESLX/projects/TLMWG/tlm2/include/tlm/tlm_h/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_h/tlm_req_rsp/tlm_1_interfaces/tlm_fifo_ifs.h"
00038 #include "tlm_h/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_h/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_put_get.h"
00257 #include "tlm_h/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_peek.h"
00258 #include "tlm_h/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_resize.h"
00259 
00260 #endif
00261 

Generated on Thu Jun 5 17:43:03 2008 for TLM 2 by  doxygen 1.5.3