summaryrefslogtreecommitdiff
path: root/ext/systemc/src/sysc/communication/sc_fifo.h
diff options
context:
space:
mode:
Diffstat (limited to 'ext/systemc/src/sysc/communication/sc_fifo.h')
-rw-r--r--ext/systemc/src/sysc/communication/sc_fifo.h479
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!