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-2006 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 //$Log: sc_fifo.h,v $
00036 //Revision 1.1.1.1  2006/12/15 20:31:35  acg
00037 //SystemC 2.2
00038 //
00039 //Revision 1.4  2006/01/24 20:46:31  acg
00040 //Andy Goodrich: changes to eliminate use of deprecated features. For instance,
00041 //using notify(SC_ZERO_TIME) in place of notify_delayed().
00042 //
00043 //Revision 1.3  2006/01/13 20:41:59  acg
00044 //Andy Goodrich: Changes to add port registration to the things that are
00045 //checked when SC_NO_WRITE_CHECK is not defined.
00046 //
00047 //Revision 1.2  2006/01/03 23:18:26  acg
00048 //Changed copyright to include 2006.
00049 //
00050 //Revision 1.1.1.1  2005/12/19 23:16:43  acg
00051 //First check in of SystemC 2.1 into its own archive.
00052 //
00053 //Revision 1.12  2005/09/15 23:01:51  acg
00054 //Added std:: prefix to appropriate methods and types to get around
00055 //issues with the Edison Front End.
00056 //
00057 //Revision 1.11  2005/06/10 22:43:55  acg
00058 //Added CVS change log annotation.
00059 //
00060 
00061 #ifndef SC_FIFO_H
00062 #define SC_FIFO_H
00063 
00064 
00065 #include "sysc/communication/sc_communication_ids.h"
00066 #include "sysc/communication/sc_prim_channel.h"
00067 #include "sysc/communication/sc_fifo_ifs.h"
00068 #include "sysc/kernel/sc_event.h"
00069 #include "sysc/kernel/sc_simcontext.h"
00070 #include "sysc/utils/sc_string.h"
00071 #include "sysc/tracing/sc_trace.h"
00072 #include <typeinfo>
00073 
00074 namespace sc_core {
00075 
00076 // ----------------------------------------------------------------------------
00077 //  CLASS : sc_fifo<T>
00078 //
00079 //  The sc_fifo<T> primitive channel class.
00080 // ----------------------------------------------------------------------------
00081 
00082 template <class T>
00083 class sc_fifo
00084 : public sc_fifo_in_if<T>,
00085   public sc_fifo_out_if<T>,
00086   public sc_prim_channel
00087 {
00088 public:
00089 
00090     // constructors
00091 
00092     explicit sc_fifo( int size_ = 16 )
00093     : sc_prim_channel( sc_gen_unique_name( "fifo" ) )
00094     { init( size_ ); }
00095 
00096     explicit sc_fifo( const char* name_, int size_ = 16 )
00097     : sc_prim_channel( name_ )
00098     { init( size_ ); }
00099 
00100 
00101     // destructor
00102 
00103     virtual ~sc_fifo()
00104     { delete [] m_buf; }
00105 
00106 
00107     // interface methods
00108 
00109     virtual void register_port( sc_port_base&, const char* );
00110 
00111 
00112     // blocking read
00113     virtual void read( T& );
00114     virtual T read();
00115 
00116     // non-blocking read
00117     virtual bool nb_read( T& );
00118 
00119 
00120     // get the number of available samples
00121 
00122     virtual int num_available() const
00123     { return ( m_num_readable - m_num_read ); }
00124 
00125 
00126     // get the data written event
00127 
00128     virtual const sc_event& data_written_event() const
00129     { return m_data_written_event; }
00130 
00131 
00132     // blocking write
00133     virtual void write( const T& );
00134 
00135     // non-blocking write
00136     virtual bool nb_write( const T& );
00137 
00138 
00139     // get the number of free spaces
00140 
00141     virtual int num_free() const
00142     { return ( m_size - m_num_readable - m_num_written ); }
00143 
00144 
00145     // get the data read event
00146 
00147     virtual const sc_event& data_read_event() const
00148     { return m_data_read_event; }
00149 
00150 
00151     // other methods
00152 
00153     operator T ()
00154     { return read(); }
00155 
00156 
00157     sc_fifo<T>& operator = ( const T& a )
00158         { write( a ); return *this; }
00159 
00160 
00161     void trace( sc_trace_file* tf ) const;
00162 
00163 
00164     virtual void print( ::std::ostream& = ::std::cout ) const;
00165     virtual void dump( ::std::ostream& = ::std::cout ) const;
00166 
00167     virtual const char* kind() const
00168         { return "sc_fifo"; }
00169 
00170 protected:
00171 
00172     virtual void update();
00173 
00174     // support methods
00175 
00176     void init( int );
00177 
00178     void buf_init( int );
00179     bool buf_write( const T& );
00180     bool buf_read( T& );
00181 
00182 protected:
00183 
00184     int m_size;         // size of the buffer
00185     T*  m_buf;          // the buffer
00186     int m_free;         // number of free spaces
00187     int m_ri;           // index of next read
00188     int m_wi;           // index of next write
00189 
00190     sc_port_base* m_reader; // used for static design rule checking
00191     sc_port_base* m_writer; // used for static design rule checking
00192 
00193     int m_num_readable;     // #samples readable
00194     int m_num_read;     // #samples read during this delta cycle
00195     int m_num_written;      // #samples written during this delta cycle
00196 
00197     sc_event m_data_read_event;
00198     sc_event m_data_written_event;
00199 
00200 private:
00201 
00202     // disabled
00203     sc_fifo( const sc_fifo<T>& );
00204     sc_fifo& operator = ( const sc_fifo<T>& );
00205 };
00206 
00207 
00208 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00209 
00210 template <class T>
00211 inline
00212 void
00213 sc_fifo<T>::register_port( sc_port_base& port_,
00214                 const char* if_typename_ )
00215 {
00216     std::string nm( if_typename_ );
00217     if( nm == typeid( sc_fifo_in_if<T> ).name() ) {
00218     // only one reader can be connected
00219     if( m_reader != 0 ) {
00220         SC_REPORT_ERROR( SC_ID_MORE_THAN_ONE_FIFO_READER_, 0 );
00221     }
00222     m_reader = &port_;
00223     } else {  // nm == typeid( sc_fifo_out_if<T> ).name()
00224     // only one writer can be connected
00225     if( m_writer != 0 ) {
00226         SC_REPORT_ERROR( SC_ID_MORE_THAN_ONE_FIFO_WRITER_, 0 );
00227     }
00228     m_writer = &port_;
00229     }
00230 }
00231 
00232 
00233 // blocking read
00234 
00235 template <class T>
00236 inline
00237 void
00238 sc_fifo<T>::read( T& val_ )
00239 {
00240     while( num_available() == 0 ) {
00241     sc_core::wait( m_data_written_event );
00242     }
00243     m_num_read ++;
00244     buf_read( val_ );
00245     request_update();
00246 }
00247 
00248 template <class T>
00249 inline
00250 T
00251 sc_fifo<T>::read()
00252 {
00253     T tmp;
00254     read( tmp );
00255     return tmp;
00256 }
00257 
00258 // non-blocking read
00259 
00260 template <class T>
00261 inline
00262 bool
00263 sc_fifo<T>::nb_read( T& val_ )
00264 {
00265     if( num_available() == 0 ) {
00266     return false;
00267     }
00268     m_num_read ++;
00269     buf_read( val_ );
00270     request_update();
00271     return true;
00272 }
00273 
00274 
00275 // blocking write
00276 
00277 template <class T>
00278 inline
00279 void
00280 sc_fifo<T>::write( const T& val_ )
00281 {
00282     while( num_free() == 0 ) {
00283     sc_core::wait( m_data_read_event );
00284     }
00285     m_num_written ++;
00286     buf_write( val_ );
00287     request_update();
00288 }
00289 
00290 // non-blocking write
00291 
00292 template <class T>
00293 inline
00294 bool
00295 sc_fifo<T>::nb_write( const T& val_ )
00296 {
00297     if( num_free() == 0 ) {
00298     return false;
00299     }
00300     m_num_written ++;
00301     buf_write( val_ );
00302     request_update();
00303     return true;
00304 }
00305 
00306 
00307 template <class T>
00308 inline
00309 void
00310 sc_fifo<T>::trace( sc_trace_file* tf ) const
00311 {
00312 #if defined(DEBUG_SYSTEMC)
00313     char buf[32];
00314     std::string nm = name();
00315     for( int i = 0; i < m_size; ++ i ) {
00316     std::sprintf( buf, "_%d", i );
00317     sc_trace( tf, m_buf[i], nm + buf );
00318     }
00319 #endif
00320 }
00321 
00322 
00323 template <class T>
00324 inline
00325 void
00326 sc_fifo<T>::print( ::std::ostream& os ) const
00327 {
00328     if( m_free != m_size ) {
00329         int i = m_ri;
00330         do {
00331             os << m_buf[i] << ::std::endl;
00332             i = ( i + 1 ) % m_size;
00333         } while( i != m_wi );
00334     }
00335 }
00336 
00337 template <class T>
00338 inline
00339 void
00340 sc_fifo<T>::dump( ::std::ostream& os ) const
00341 {
00342     os << "name = " << name() << ::std::endl;
00343     if( m_free != m_size ) {
00344         int i = m_ri;
00345         int j = 0;
00346         do {
00347         os << "value[" << i << "] = " << m_buf[i] << ::std::endl;
00348         i = ( i + 1 ) % m_size;
00349         j ++;
00350         } while( i != m_wi );
00351     }
00352 }
00353 
00354 
00355 template <class T>
00356 inline
00357 void
00358 sc_fifo<T>::update()
00359 {
00360     if( m_num_read > 0 ) {
00361     m_data_read_event.notify(SC_ZERO_TIME);
00362     }
00363 
00364     if( m_num_written > 0 ) {
00365     m_data_written_event.notify(SC_ZERO_TIME);
00366     }
00367 
00368     m_num_readable = m_size - m_free;
00369     m_num_read = 0;
00370     m_num_written = 0;
00371 }
00372 
00373 
00374 // support methods
00375 
00376 template <class T>
00377 inline
00378 void
00379 sc_fifo<T>::init( int size_ )
00380 {
00381     buf_init( size_ );
00382 
00383     m_reader = 0;
00384     m_writer = 0;
00385 
00386     m_num_readable = 0;
00387     m_num_read = 0;
00388     m_num_written = 0;
00389 }
00390 
00391 
00392 template <class T>
00393 inline
00394 void
00395 sc_fifo<T>::buf_init( int size_ )
00396 {
00397     if( size_ <= 0 ) {
00398     SC_REPORT_ERROR( SC_ID_INVALID_FIFO_SIZE_, 0 );
00399     }
00400     m_size = size_;
00401     m_buf = new T[m_size];
00402     m_free = m_size;
00403     m_ri = 0;
00404     m_wi = 0;
00405 }
00406 
00407 template <class T>
00408 inline
00409 bool
00410 sc_fifo<T>::buf_write( const T& val_ )
00411 {
00412     if( m_free == 0 ) {
00413     return false;
00414     }
00415     m_buf[m_wi] = val_;
00416     m_wi = ( m_wi + 1 ) % m_size;
00417     m_free --;
00418     return true;
00419 }
00420 
00421 template <class T>
00422 inline
00423 bool
00424 sc_fifo<T>::buf_read( T& val_ )
00425 {
00426     if( m_free == m_size ) {
00427     return false;
00428     }
00429     val_ = m_buf[m_ri];
00430     m_ri = ( m_ri + 1 ) % m_size;
00431     m_free ++;
00432     return true;
00433 }
00434 
00435 
00436 // ----------------------------------------------------------------------------
00437 
00438 template <class T>
00439 inline
00440 ::std::ostream&
00441 operator << ( ::std::ostream& os, const sc_fifo<T>& a )
00442 {
00443     a.print( os );
00444     return os;
00445 }
00446 
00447 } // namespace sc_core
00448 
00449 #endif
00450 
00451 // Taf!

Generated on Wed Jan 21 15:32:06 2009 for SystemC by  doxygen 1.5.5