src/sysc/communication/sc_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-2005 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 2.4 (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 /*****************************************************************************
00019 
00020   sc_fifo.h -- The sc_fifo<T> primitive channel class.
00021 
00022   Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
00023 
00024  *****************************************************************************/
00025 
00026 /*****************************************************************************
00027 
00028   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00029   changes you are making here.
00030 
00031       Name, Affiliation, Date:
00032   Description of Modification:
00033     
00034  *****************************************************************************/
00035 
00036 #ifndef SC_FIFO_H
00037 #define SC_FIFO_H
00038 
00039 
00040 #include "sysc/communication/sc_communication_ids.h"
00041 #include "sysc/communication/sc_prim_channel.h"
00042 #include "sysc/communication/sc_fifo_ifs.h"
00043 #include "sysc/kernel/sc_event.h"
00044 #include "sysc/kernel/sc_simcontext.h"
00045 #include "sysc/utils/sc_string.h"
00046 #include "sysc/tracing/sc_trace.h"
00047 #include <typeinfo>
00048 
00049 namespace sc_core {
00050 
00051 // ----------------------------------------------------------------------------
00052 //  CLASS : sc_fifo<T>
00053 //
00054 //  The sc_fifo<T> primitive channel class.
00055 // ----------------------------------------------------------------------------
00056 
00057 template <class T>
00058 class sc_fifo
00059 : public sc_fifo_in_if<T>,
00060   public sc_fifo_out_if<T>,
00061   public sc_prim_channel
00062 {
00063 public:
00064 
00065     // constructors
00066 
00067     explicit sc_fifo( int size_ = 16 )
00068         : sc_prim_channel( sc_gen_unique_name( "fifo" ) )
00069         { init( size_ ); }
00070 
00071     explicit sc_fifo( const char* name_, int size_ = 16 )
00072         : sc_prim_channel( name_ )
00073         { init( size_ ); }
00074 
00075 
00076     // destructor
00077 
00078     virtual ~sc_fifo()
00079         { delete [] m_buf; }
00080 
00081 
00082     // interface methods
00083 
00084     virtual void register_port( sc_port_base&, const char* );
00085 
00086 
00087     // blocking read
00088     virtual void read( T& );
00089     virtual T read();
00090 
00091     // non-blocking read
00092     virtual bool nb_read( T& );
00093 
00094 
00095     // get the number of available samples
00096 
00097     virtual int num_available() const
00098         { return ( m_num_readable - m_num_read ); }
00099 
00100 
00101     // get the data written event
00102 
00103     virtual const sc_event& data_written_event() const
00104         { return m_data_written_event; }
00105 
00106 
00107     // blocking write
00108     virtual void write( const T& );
00109 
00110     // non-blocking write
00111     virtual bool nb_write( const T& );
00112 
00113 
00114     // get the number of free spaces
00115 
00116     virtual int num_free() const
00117         { return ( m_size - m_num_readable - m_num_written ); }
00118 
00119 
00120     // get the data read event
00121 
00122     virtual const sc_event& data_read_event() const
00123         { return m_data_read_event; }
00124 
00125 
00126     // other methods
00127 
00128     operator T ()
00129         { return read(); }
00130 
00131 
00132     sc_fifo<T>& operator = ( const T& a )
00133         { write( a ); return *this; }
00134 
00135 
00136     void trace( sc_trace_file* tf ) const;
00137 
00138 
00139     virtual void print( ::std::ostream& = ::std::cout ) const;
00140     virtual void dump( ::std::ostream& = ::std::cout ) const;
00141 
00142     virtual const char* kind() const
00143         { return "sc_fifo"; }
00144 
00145 protected:
00146 
00147     virtual void update();
00148 
00149     // support methods
00150 
00151     void init( int );
00152 
00153     void buf_init( int );
00154     bool buf_write( const T& );
00155     bool buf_read( T& );
00156 
00157 protected:
00158 
00159     int m_size;                 // size of the buffer
00160     T*  m_buf;                  // the buffer
00161     int m_free;                 // number of free spaces
00162     int m_ri;                   // index of next read
00163     int m_wi;                   // index of next write
00164 
00165     sc_port_base* m_reader;     // used for static design rule checking
00166     sc_port_base* m_writer;     // used for static design rule checking
00167 
00168     int m_num_readable;         // #samples readable
00169     int m_num_read;             // #samples read during this delta cycle
00170     int m_num_written;          // #samples written during this delta cycle
00171 
00172     sc_event m_data_read_event;
00173     sc_event m_data_written_event;
00174 
00175 private:
00176 
00177     // disabled
00178     sc_fifo( const sc_fifo<T>& );
00179     sc_fifo& operator = ( const sc_fifo<T>& );
00180 };
00181 
00182 
00183 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00184 
00185 template <class T>
00186 inline
00187 void
00188 sc_fifo<T>::register_port( sc_port_base& port_,
00189                             const char* if_typename_ )
00190 {
00191     std::string nm( if_typename_ );
00192     if( nm == typeid( sc_fifo_in_if<T> ).name() ) {
00193         // only one reader can be connected
00194         if( m_reader != 0 ) {
00195             SC_REPORT_ERROR( SC_ID_MORE_THAN_ONE_FIFO_READER_, 0 );
00196         }
00197         m_reader = &port_;
00198     } else {  // nm == typeid( sc_fifo_out_if<T> ).name()
00199         // only one writer can be connected
00200         if( m_writer != 0 ) {
00201             SC_REPORT_ERROR( SC_ID_MORE_THAN_ONE_FIFO_WRITER_, 0 );
00202         }
00203         m_writer = &port_;
00204     }
00205 }
00206 
00207 
00208 // blocking read
00209 
00210 template <class T>
00211 inline
00212 void
00213 sc_fifo<T>::read( T& val_ )
00214 {
00215     while( num_available() == 0 ) {
00216         sc_core::wait( m_data_written_event );
00217     }
00218     m_num_read ++;
00219     buf_read( val_ );
00220     request_update();
00221 }
00222 
00223 template <class T>
00224 inline
00225 T
00226 sc_fifo<T>::read()
00227 {
00228     T tmp;
00229     read( tmp );
00230     return tmp;
00231 }
00232 
00233 // non-blocking read
00234 
00235 template <class T>
00236 inline
00237 bool
00238 sc_fifo<T>::nb_read( T& val_ )
00239 {
00240     if( num_available() == 0 ) {
00241         return false;
00242     }
00243     m_num_read ++;
00244     buf_read( val_ );
00245     request_update();
00246     return true;
00247 }
00248 
00249 
00250 // blocking write
00251 
00252 template <class T>
00253 inline
00254 void
00255 sc_fifo<T>::write( const T& val_ )
00256 {
00257     while( num_free() == 0 ) {
00258         sc_core::wait( m_data_read_event );
00259     }
00260     m_num_written ++;
00261     buf_write( val_ );
00262     request_update();
00263 }
00264 
00265 // non-blocking write
00266 
00267 template <class T>
00268 inline
00269 bool
00270 sc_fifo<T>::nb_write( const T& val_ )
00271 {
00272     if( num_free() == 0 ) {
00273         return false;
00274     }
00275     m_num_written ++;
00276     buf_write( val_ );
00277     request_update();
00278     return true;
00279 }
00280 
00281 
00282 template <class T>
00283 inline
00284 void
00285 sc_fifo<T>::trace( sc_trace_file* tf ) const
00286 {
00287 #ifdef DEBUG_SYSTEMC
00288     char buf[32];
00289     std::string nm = name();
00290     for( int i = 0; i < m_size; ++ i ) {
00291         sprintf( buf, "_%d", i );
00292         sc_trace( tf, m_buf[i], nm + buf );
00293     }
00294 #endif
00295 }
00296 
00297 
00298 template <class T>
00299 inline
00300 void
00301 sc_fifo<T>::print( ::std::ostream& os ) const
00302 {
00303     if( m_free != m_size ) {
00304         int i = m_ri;
00305         do {
00306             os << m_buf[i] << ::std::endl;
00307             i = ( i + 1 ) % m_size;
00308         } while( i != m_wi );
00309     }
00310 }
00311 
00312 template <class T>
00313 inline
00314 void
00315 sc_fifo<T>::dump( ::std::ostream& os ) const
00316 {
00317     os << "name = " << name() << ::std::endl;
00318     if( m_free != m_size ) {
00319         int i = m_ri;
00320         int j = 0;
00321         do {
00322             os << "value[" << i << "] = " << m_buf[i] << ::std::endl;
00323             i = ( i + 1 ) % m_size;
00324             j ++;
00325         } while( i != m_wi );
00326     }
00327 }
00328 
00329 
00330 template <class T>
00331 inline
00332 void
00333 sc_fifo<T>::update()
00334 {
00335     if( m_num_read > 0 ) {
00336         m_data_read_event.notify_delayed();
00337     }
00338 
00339     if( m_num_written > 0 ) {
00340         m_data_written_event.notify_delayed();
00341     }
00342 
00343     m_num_readable = m_size - m_free;
00344     m_num_read = 0;
00345     m_num_written = 0;
00346 }
00347 
00348 
00349 // support methods
00350 
00351 template <class T>
00352 inline
00353 void
00354 sc_fifo<T>::init( int size_ )
00355 {
00356     buf_init( size_ );
00357 
00358     m_reader = 0;
00359     m_writer = 0;
00360 
00361     m_num_readable = 0;
00362     m_num_read = 0;
00363     m_num_written = 0;
00364 }
00365 
00366 
00367 template <class T>
00368 inline
00369 void
00370 sc_fifo<T>::buf_init( int size_ )
00371 {
00372     if( size_ <= 0 ) {
00373         SC_REPORT_ERROR( SC_ID_INVALID_FIFO_SIZE_, 0 );
00374     }
00375     m_size = size_;
00376     m_buf = new T[m_size];
00377     m_free = m_size;
00378     m_ri = 0;
00379     m_wi = 0;
00380 }
00381 
00382 template <class T>
00383 inline
00384 bool
00385 sc_fifo<T>::buf_write( const T& val_ )
00386 {
00387     if( m_free == 0 ) {
00388         return false;
00389     }
00390     m_buf[m_wi] = val_;
00391     m_wi = ( m_wi + 1 ) % m_size;
00392     m_free --;
00393     return true;
00394 }
00395 
00396 template <class T>
00397 inline
00398 bool
00399 sc_fifo<T>::buf_read( T& val_ )
00400 {
00401     if( m_free == m_size ) {
00402         return false;
00403     }
00404     val_ = m_buf[m_ri];
00405     m_ri = ( m_ri + 1 ) % m_size;
00406     m_free ++;
00407     return true;
00408 }
00409 
00410 
00411 // ----------------------------------------------------------------------------
00412 
00413 template <class T>
00414 inline
00415 ::std::ostream&
00416 operator << ( ::std::ostream& os, const sc_fifo<T>& a )
00417 {
00418     a.print( os );
00419     return os;
00420 }
00421 
00422 } // namespace sc_core
00423 
00424 #endif
00425 
00426 // Taf!

Generated on Wed Apr 25 13:53:25 2007 for SystemC by  doxygen 1.5.1