diff options
Diffstat (limited to 'ext/systemc/src/sysc/communication/sc_fifo.h')
-rw-r--r-- | ext/systemc/src/sysc/communication/sc_fifo.h | 479 |
1 files changed, 479 insertions, 0 deletions
diff --git a/ext/systemc/src/sysc/communication/sc_fifo.h b/ext/systemc/src/sysc/communication/sc_fifo.h new file mode 100644 index 000000000..868c0304e --- /dev/null +++ b/ext/systemc/src/sysc/communication/sc_fifo.h @@ -0,0 +1,479 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fifo.h -- The sc_fifo<T> primitive channel class. + + Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21 + + CHANGE LOG IS AT THE END OF THE FILE + *****************************************************************************/ + +#ifndef SC_FIFO_H +#define SC_FIFO_H + + +#include "sysc/communication/sc_communication_ids.h" +#include "sysc/communication/sc_prim_channel.h" +#include "sysc/communication/sc_fifo_ifs.h" +#include "sysc/kernel/sc_event.h" +#include "sysc/kernel/sc_simcontext.h" +#include "sysc/tracing/sc_trace.h" +#include <typeinfo> + +namespace sc_core { + +// ---------------------------------------------------------------------------- +// CLASS : sc_fifo<T> +// +// The sc_fifo<T> primitive channel class. +// ---------------------------------------------------------------------------- + +template <class T> +class sc_fifo +: public sc_fifo_in_if<T>, + public sc_fifo_out_if<T>, + public sc_prim_channel +{ +public: + + // constructors + + explicit sc_fifo( int size_ = 16 ) + : sc_prim_channel( sc_gen_unique_name( "fifo" ) ), + m_data_read_event( + (std::string(SC_KERNEL_EVENT_PREFIX)+"_read_event").c_str()), + m_data_written_event( + (std::string(SC_KERNEL_EVENT_PREFIX)+"_write_event").c_str()) + { init( size_ ); } + + explicit sc_fifo( const char* name_, int size_ = 16 ) + : sc_prim_channel( name_ ), + m_data_read_event( + (std::string(SC_KERNEL_EVENT_PREFIX)+"_read_event").c_str()), + m_data_written_event( + (std::string(SC_KERNEL_EVENT_PREFIX)+"_write_event").c_str()) + { init( size_ ); } + + + // destructor + + virtual ~sc_fifo() + { delete [] m_buf; } + + + // interface methods + + virtual void register_port( sc_port_base&, const char* ); + + + // blocking read + virtual void read( T& ); + virtual T read(); + + // non-blocking read + virtual bool nb_read( T& ); + + + // get the number of available samples + + virtual int num_available() const + { return ( m_num_readable - m_num_read ); } + + + // get the data written event + + virtual const sc_event& data_written_event() const + { return m_data_written_event; } + + + // blocking write + virtual void write( const T& ); + + // non-blocking write + virtual bool nb_write( const T& ); + + + // get the number of free spaces + + virtual int num_free() const + { return ( m_size - m_num_readable - m_num_written ); } + + + // get the data read event + + virtual const sc_event& data_read_event() const + { return m_data_read_event; } + + + // other methods + + operator T () + { return read(); } + + + sc_fifo<T>& operator = ( const T& a ) + { write( a ); return *this; } + + + void trace( sc_trace_file* tf ) const; + + + virtual void print( ::std::ostream& = ::std::cout ) const; + virtual void dump( ::std::ostream& = ::std::cout ) const; + + virtual const char* kind() const + { return "sc_fifo"; } + +protected: + + virtual void update(); + + // support methods + + void init( int ); + + void buf_init( int ); + bool buf_write( const T& ); + bool buf_read( T& ); + +protected: + + int m_size; // size of the buffer + T* m_buf; // the buffer + int m_free; // number of free spaces + int m_ri; // index of next read + int m_wi; // index of next write + + sc_port_base* m_reader; // used for static design rule checking + sc_port_base* m_writer; // used for static design rule checking + + int m_num_readable; // #samples readable + int m_num_read; // #samples read during this delta cycle + int m_num_written; // #samples written during this delta cycle + + sc_event m_data_read_event; + sc_event m_data_written_event; + +private: + + // disabled + sc_fifo( const sc_fifo<T>& ); + sc_fifo& operator = ( const sc_fifo<T>& ); +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +template <class T> +inline +void +sc_fifo<T>::register_port( sc_port_base& port_, + const char* if_typename_ ) +{ + std::string nm( if_typename_ ); + if( nm == typeid( sc_fifo_in_if<T> ).name() || + nm == typeid( sc_fifo_blocking_in_if<T> ).name() + ) { + // only one reader can be connected + if( m_reader != 0 ) { + SC_REPORT_ERROR( SC_ID_MORE_THAN_ONE_FIFO_READER_, 0 ); + } + m_reader = &port_; + } else if( nm == typeid( sc_fifo_out_if<T> ).name() || + nm == typeid( sc_fifo_blocking_out_if<T> ).name() + ) { + // only one writer can be connected + if( m_writer != 0 ) { + SC_REPORT_ERROR( SC_ID_MORE_THAN_ONE_FIFO_WRITER_, 0 ); + } + m_writer = &port_; + } + else + { + SC_REPORT_ERROR( SC_ID_BIND_IF_TO_PORT_, + "sc_fifo<T> port not recognized" ); + } +} + + +// blocking read + +template <class T> +inline +void +sc_fifo<T>::read( T& val_ ) +{ + while( num_available() == 0 ) { + sc_core::wait( m_data_written_event ); + } + m_num_read ++; + buf_read( val_ ); + request_update(); +} + +template <class T> +inline +T +sc_fifo<T>::read() +{ + T tmp; + read( tmp ); + return tmp; +} + +// non-blocking read + +template <class T> +inline +bool +sc_fifo<T>::nb_read( T& val_ ) +{ + if( num_available() == 0 ) { + return false; + } + m_num_read ++; + buf_read( val_ ); + request_update(); + return true; +} + + +// blocking write + +template <class T> +inline +void +sc_fifo<T>::write( const T& val_ ) +{ + while( num_free() == 0 ) { + sc_core::wait( m_data_read_event ); + } + m_num_written ++; + buf_write( val_ ); + request_update(); +} + +// non-blocking write + +template <class T> +inline +bool +sc_fifo<T>::nb_write( const T& val_ ) +{ + if( num_free() == 0 ) { + return false; + } + m_num_written ++; + buf_write( val_ ); + request_update(); + return true; +} + + +template <class T> +inline +void +sc_fifo<T>::trace( sc_trace_file* tf ) const +{ +#if defined(DEBUG_SYSTEMC) + char buf[32]; + std::string nm = name(); + for( int i = 0; i < m_size; ++ i ) { + std::sprintf( buf, "_%d", i ); + sc_trace( tf, m_buf[i], nm + buf ); + } +#endif +} + + +template <class T> +inline +void +sc_fifo<T>::print( ::std::ostream& os ) const +{ + if( m_free != m_size ) { + int i = m_ri; + do { + os << m_buf[i] << ::std::endl; + i = ( i + 1 ) % m_size; + } while( i != m_wi ); + } +} + +template <class T> +inline +void +sc_fifo<T>::dump( ::std::ostream& os ) const +{ + os << "name = " << name() << ::std::endl; + if( m_free != m_size ) { + int i = m_ri; + int j = 0; + do { + os << "value[" << i << "] = " << m_buf[i] << ::std::endl; + i = ( i + 1 ) % m_size; + j ++; + } while( i != m_wi ); + } +} + + +template <class T> +inline +void +sc_fifo<T>::update() +{ + if( m_num_read > 0 ) { + m_data_read_event.notify(SC_ZERO_TIME); + } + + if( m_num_written > 0 ) { + m_data_written_event.notify(SC_ZERO_TIME); + } + + m_num_readable = m_size - m_free; + m_num_read = 0; + m_num_written = 0; +} + + +// support methods + +template <class T> +inline +void +sc_fifo<T>::init( int size_ ) +{ + buf_init( size_ ); + + m_reader = 0; + m_writer = 0; + + m_num_readable = 0; + m_num_read = 0; + m_num_written = 0; +} + + +template <class T> +inline +void +sc_fifo<T>::buf_init( int size_ ) +{ + if( size_ <= 0 ) { + SC_REPORT_ERROR( SC_ID_INVALID_FIFO_SIZE_, 0 ); + } + m_size = size_; + m_buf = new T[m_size]; + m_free = m_size; + m_ri = 0; + m_wi = 0; +} + +template <class T> +inline +bool +sc_fifo<T>::buf_write( const T& val_ ) +{ + if( m_free == 0 ) { + return false; + } + m_buf[m_wi] = val_; + m_wi = ( m_wi + 1 ) % m_size; + m_free --; + return true; +} + +template <class T> +inline +bool +sc_fifo<T>::buf_read( T& val_ ) +{ + if( m_free == m_size ) { + return false; + } + val_ = m_buf[m_ri]; + m_buf[m_ri] = T(); // clear entry for boost::shared_ptr, et al. + m_ri = ( m_ri + 1 ) % m_size; + m_free ++; + return true; +} + + +// ---------------------------------------------------------------------------- + +template <class T> +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_fifo<T>& a ) +{ + a.print( os ); + return os; +} + +} // namespace sc_core + +//$Log: sc_fifo.h,v $ +//Revision 1.6 2011/08/26 20:45:40 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +//Revision 1.5 2011/03/23 16:17:22 acg +// Andy Goodrich: hide the sc_events that are kernel related. +// +//Revision 1.4 2011/02/18 20:23:45 acg +// Andy Goodrich: Copyright update. +// +//Revision 1.3 2009/10/14 19:05:40 acg +// Andy Goodrich: added check for blocking interfaces in addition to the +// combined blocking/nonblocking interface. +// +//Revision 1.2 2009/05/22 16:06:24 acg +// Andy Goodrich: process control updates. +// +//Revision 1.1.1.1 2006/12/15 20:20:04 acg +//SystemC 2.3 +// +//Revision 1.4 2006/01/24 20:46:31 acg +//Andy Goodrich: changes to eliminate use of deprecated features. For instance, +//using notify(SC_ZERO_TIME) in place of notify_delayed(). +// +//Revision 1.3 2006/01/13 20:41:59 acg +//Andy Goodrich: Changes to add port registration to the things that are +//checked when SC_NO_WRITE_CHECK is not defined. +// +//Revision 1.2 2006/01/03 23:18:26 acg +//Changed copyright to include 2006. +// +//Revision 1.1.1.1 2005/12/19 23:16:43 acg +//First check in of SystemC 2.1 into its own archive. +// +//Revision 1.12 2005/09/15 23:01:51 acg +//Added std:: prefix to appropriate methods and types to get around +//issues with the Edison Front End. +// +//Revision 1.11 2005/06/10 22:43:55 acg +//Added CVS change log annotation. +// + +#endif + +// Taf! |