SystemC  2.3.1
Accellera SystemC proof-of-concept library
sc_fifo.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  The following code is derived, directly or indirectly, from the SystemC
4  source code Copyright (c) 1996-2014 by all Contributors.
5  All Rights reserved.
6 
7  The contents of this file are subject to the restrictions and limitations
8  set forth in the SystemC Open Source License (the "License");
9  You may not use this file except in compliance with such restrictions and
10  limitations. You may obtain instructions on how to receive a copy of the
11  License at http://www.accellera.org/. Software distributed by Contributors
12  under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
13  ANY KIND, either express or implied. See the License for the specific
14  language governing rights and limitations under the License.
15 
16  *****************************************************************************/
17 
18 /*****************************************************************************
19 
20  sc_fifo.h -- The sc_fifo<T> primitive channel class.
21 
22  Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
23 
24  CHANGE LOG IS AT THE END OF THE FILE
25  *****************************************************************************/
26 
27 #ifndef SC_FIFO_H
28 #define SC_FIFO_H
29 
30 
34 #include "sysc/kernel/sc_event.h"
36 #include "sysc/tracing/sc_trace.h"
37 #include <typeinfo>
38 
39 namespace sc_core {
40 
41 // ----------------------------------------------------------------------------
42 // CLASS : sc_fifo<T>
43 //
44 // The sc_fifo<T> primitive channel class.
45 // ----------------------------------------------------------------------------
46 
47 template <class T>
48 class sc_fifo
49 : public sc_fifo_in_if<T>,
50  public sc_fifo_out_if<T>,
51  public sc_prim_channel
52 {
53 public:
54 
55  // constructors
56 
57  explicit sc_fifo( int size_ = 16 )
58  : sc_prim_channel( sc_gen_unique_name( "fifo" ) ),
60  (std::string(SC_KERNEL_EVENT_PREFIX)+"_read_event").c_str()),
62  (std::string(SC_KERNEL_EVENT_PREFIX)+"_write_event").c_str())
63  { init( size_ ); }
64 
65  explicit sc_fifo( const char* name_, int size_ = 16 )
66  : sc_prim_channel( name_ ),
68  (std::string(SC_KERNEL_EVENT_PREFIX)+"_read_event").c_str()),
70  (std::string(SC_KERNEL_EVENT_PREFIX)+"_write_event").c_str())
71  { init( size_ ); }
72 
73 
74  // destructor
75 
76  virtual ~sc_fifo()
77  { delete [] m_buf; }
78 
79 
80  // interface methods
81 
82  virtual void register_port( sc_port_base&, const char* );
83 
84 
85  // blocking read
86  virtual void read( T& );
87  virtual T read();
88 
89  // non-blocking read
90  virtual bool nb_read( T& );
91 
92 
93  // get the number of available samples
94 
95  virtual int num_available() const
96  { return ( m_num_readable - m_num_read ); }
97 
98 
99  // get the data written event
100 
101  virtual const sc_event& data_written_event() const
102  { return m_data_written_event; }
103 
104 
105  // blocking write
106  virtual void write( const T& );
107 
108  // non-blocking write
109  virtual bool nb_write( const T& );
110 
111 
112  // get the number of free spaces
113 
114  virtual int num_free() const
115  { return ( m_size - m_num_readable - m_num_written ); }
116 
117 
118  // get the data read event
119 
120  virtual const sc_event& data_read_event() const
121  { return m_data_read_event; }
122 
123 
124  // other methods
125 
126  operator T ()
127  { return read(); }
128 
129 
130  sc_fifo<T>& operator = ( const T& a )
131  { write( a ); return *this; }
132 
133 
134  void trace( sc_trace_file* tf ) const;
135 
136 
137  virtual void print( ::std::ostream& = ::std::cout ) const;
138  virtual void dump( ::std::ostream& = ::std::cout ) const;
139 
140  virtual const char* kind() const
141  { return "sc_fifo"; }
142 
143 protected:
144 
145  virtual void update();
146 
147  // support methods
148 
149  void init( int );
150 
151  void buf_init( int );
152  bool buf_write( const T& );
153  bool buf_read( T& );
154 
155 protected:
156 
157  int m_size; // size of the buffer
158  T* m_buf; // the buffer
159  int m_free; // number of free spaces
160  int m_ri; // index of next read
161  int m_wi; // index of next write
162 
163  sc_port_base* m_reader; // used for static design rule checking
164  sc_port_base* m_writer; // used for static design rule checking
165 
166  int m_num_readable; // #samples readable
167  int m_num_read; // #samples read during this delta cycle
168  int m_num_written; // #samples written during this delta cycle
169 
172 
173 private:
174 
175  // disabled
176  sc_fifo( const sc_fifo<T>& );
177  sc_fifo& operator = ( const sc_fifo<T>& );
178 };
179 
180 
181 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
182 
183 template <class T>
184 inline
185 void
187  const char* if_typename_ )
188 {
189  std::string nm( if_typename_ );
190  if( nm == typeid( sc_fifo_in_if<T> ).name() ||
191  nm == typeid( sc_fifo_blocking_in_if<T> ).name()
192  ) {
193  // only one reader can be connected
194  if( m_reader != 0 ) {
195  SC_REPORT_ERROR( SC_ID_MORE_THAN_ONE_FIFO_READER_, 0 );
196  }
197  m_reader = &port_;
198  } else if( nm == typeid( sc_fifo_out_if<T> ).name() ||
199  nm == typeid( sc_fifo_blocking_out_if<T> ).name()
200  ) {
201  // only one writer can be connected
202  if( m_writer != 0 ) {
203  SC_REPORT_ERROR( SC_ID_MORE_THAN_ONE_FIFO_WRITER_, 0 );
204  }
205  m_writer = &port_;
206  }
207  else
208  {
209  SC_REPORT_ERROR( SC_ID_BIND_IF_TO_PORT_,
210  "sc_fifo<T> port not recognized" );
211  }
212 }
213 
214 
215 // blocking read
216 
217 template <class T>
218 inline
219 void
221 {
222  while( num_available() == 0 ) {
223  sc_core::wait( m_data_written_event );
224  }
225  m_num_read ++;
226  buf_read( val_ );
227  request_update();
228 }
229 
230 template <class T>
231 inline
232 T
234 {
235  T tmp;
236  read( tmp );
237  return tmp;
238 }
239 
240 // non-blocking read
241 
242 template <class T>
243 inline
244 bool
246 {
247  if( num_available() == 0 ) {
248  return false;
249  }
250  m_num_read ++;
251  buf_read( val_ );
252  request_update();
253  return true;
254 }
255 
256 
257 // blocking write
258 
259 template <class T>
260 inline
261 void
262 sc_fifo<T>::write( const T& val_ )
263 {
264  while( num_free() == 0 ) {
265  sc_core::wait( m_data_read_event );
266  }
267  m_num_written ++;
268  buf_write( val_ );
269  request_update();
270 }
271 
272 // non-blocking write
273 
274 template <class T>
275 inline
276 bool
277 sc_fifo<T>::nb_write( const T& val_ )
278 {
279  if( num_free() == 0 ) {
280  return false;
281  }
282  m_num_written ++;
283  buf_write( val_ );
284  request_update();
285  return true;
286 }
287 
288 
289 template <class T>
290 inline
291 void
293 {
294 #if defined(DEBUG_SYSTEMC)
295  char buf[32];
296  std::string nm = name();
297  for( int i = 0; i < m_size; ++ i ) {
298  std::sprintf( buf, "_%d", i );
299  sc_trace( tf, m_buf[i], nm + buf );
300  }
301 #endif
302 }
303 
304 
305 template <class T>
306 inline
307 void
308 sc_fifo<T>::print( ::std::ostream& os ) const
309 {
310  if( m_free != m_size ) {
311  int i = m_ri;
312  do {
313  os << m_buf[i] << ::std::endl;
314  i = ( i + 1 ) % m_size;
315  } while( i != m_wi );
316  }
317 }
318 
319 template <class T>
320 inline
321 void
322 sc_fifo<T>::dump( ::std::ostream& os ) const
323 {
324  os << "name = " << name() << ::std::endl;
325  if( m_free != m_size ) {
326  int i = m_ri;
327  int j = 0;
328  do {
329  os << "value[" << i << "] = " << m_buf[i] << ::std::endl;
330  i = ( i + 1 ) % m_size;
331  j ++;
332  } while( i != m_wi );
333  }
334 }
335 
336 
337 template <class T>
338 inline
339 void
341 {
342  if( m_num_read > 0 ) {
343  m_data_read_event.notify(SC_ZERO_TIME);
344  }
345 
346  if( m_num_written > 0 ) {
347  m_data_written_event.notify(SC_ZERO_TIME);
348  }
349 
350  m_num_readable = m_size - m_free;
351  m_num_read = 0;
352  m_num_written = 0;
353 }
354 
355 
356 // support methods
357 
358 template <class T>
359 inline
360 void
361 sc_fifo<T>::init( int size_ )
362 {
363  buf_init( size_ );
364 
365  m_reader = 0;
366  m_writer = 0;
367 
368  m_num_readable = 0;
369  m_num_read = 0;
370  m_num_written = 0;
371 }
372 
373 
374 template <class T>
375 inline
376 void
378 {
379  if( size_ <= 0 ) {
380  SC_REPORT_ERROR( SC_ID_INVALID_FIFO_SIZE_, 0 );
381  }
382  m_size = size_;
383  m_buf = new T[m_size];
384  m_free = m_size;
385  m_ri = 0;
386  m_wi = 0;
387 }
388 
389 template <class T>
390 inline
391 bool
392 sc_fifo<T>::buf_write( const T& val_ )
393 {
394  if( m_free == 0 ) {
395  return false;
396  }
397  m_buf[m_wi] = val_;
398  m_wi = ( m_wi + 1 ) % m_size;
399  m_free --;
400  return true;
401 }
402 
403 template <class T>
404 inline
405 bool
407 {
408  if( m_free == m_size ) {
409  return false;
410  }
411  val_ = m_buf[m_ri];
412  m_buf[m_ri] = T(); // clear entry for boost::shared_ptr, et al.
413  m_ri = ( m_ri + 1 ) % m_size;
414  m_free ++;
415  return true;
416 }
417 
418 
419 // ----------------------------------------------------------------------------
420 
421 template <class T>
422 inline
423 ::std::ostream&
424 operator << ( ::std::ostream& os, const sc_fifo<T>& a )
425 {
426  a.print( os );
427  return os;
428 }
429 
430 } // namespace sc_core
431 
432 //$Log: sc_fifo.h,v $
433 //Revision 1.6 2011/08/26 20:45:40 acg
434 // Andy Goodrich: moved the modification log to the end of the file to
435 // eliminate source line number skew when check-ins are done.
436 //
437 //Revision 1.5 2011/03/23 16:17:22 acg
438 // Andy Goodrich: hide the sc_events that are kernel related.
439 //
440 //Revision 1.4 2011/02/18 20:23:45 acg
441 // Andy Goodrich: Copyright update.
442 //
443 //Revision 1.3 2009/10/14 19:05:40 acg
444 // Andy Goodrich: added check for blocking interfaces in addition to the
445 // combined blocking/nonblocking interface.
446 //
447 //Revision 1.2 2009/05/22 16:06:24 acg
448 // Andy Goodrich: process control updates.
449 //
450 //Revision 1.1.1.1 2006/12/15 20:20:04 acg
451 //SystemC 2.3
452 //
453 //Revision 1.4 2006/01/24 20:46:31 acg
454 //Andy Goodrich: changes to eliminate use of deprecated features. For instance,
455 //using notify(SC_ZERO_TIME) in place of notify_delayed().
456 //
457 //Revision 1.3 2006/01/13 20:41:59 acg
458 //Andy Goodrich: Changes to add port registration to the things that are
459 //checked when SC_NO_WRITE_CHECK is not defined.
460 //
461 //Revision 1.2 2006/01/03 23:18:26 acg
462 //Changed copyright to include 2006.
463 //
464 //Revision 1.1.1.1 2005/12/19 23:16:43 acg
465 //First check in of SystemC 2.1 into its own archive.
466 //
467 //Revision 1.12 2005/09/15 23:01:51 acg
468 //Added std:: prefix to appropriate methods and types to get around
469 //issues with the Edison Front End.
470 //
471 //Revision 1.11 2005/06/10 22:43:55 acg
472 //Added CVS change log annotation.
473 //
474 
475 #endif
476 
477 // Taf!
void wait(int, sc_simcontext *)
sc_fifo(const char *name_, int size_=16)
Definition: sc_fifo.h:65
bool buf_read(T &)
Definition: sc_fifo.h:406
sc_fifo(int size_=16)
Definition: sc_fifo.h:57
virtual void write(const T &)
Definition: sc_fifo.h:262
virtual const char * kind() const
Definition: sc_fifo.h:140
virtual ~sc_fifo()
Definition: sc_fifo.h:76
virtual void register_port(sc_port_base &, const char *)
Definition: sc_fifo.h:186
virtual bool nb_write(const T &)
Definition: sc_fifo.h:277
sc_port_base * m_writer
Definition: sc_fifo.h:164
virtual const sc_event & data_read_event() const
Definition: sc_fifo.h:120
sc_event m_data_written_event
Definition: sc_fifo.h:171
sc_fifo< T > & operator=(const T &a)
Definition: sc_fifo.h:130
const char * sc_gen_unique_name(const char *, bool preserve_first)
sc_port_base * m_reader
Definition: sc_fifo.h:163
virtual int num_available() const
Definition: sc_fifo.h:95
sc_event m_data_read_event
Definition: sc_fifo.h:170
virtual T read()
Definition: sc_fifo.h:233
virtual void print(::std::ostream &=::std::cout) const
Definition: sc_fifo.h:308
virtual bool nb_read(T &)
Definition: sc_fifo.h:245
bool buf_write(const T &)
Definition: sc_fifo.h:392
const sc_time SC_ZERO_TIME
#define SC_REPORT_ERROR(msg_type, msg)
Definition: sc_report.h:213
void buf_init(int)
Definition: sc_fifo.h:377
void init(int)
Definition: sc_fifo.h:361
virtual const sc_event & data_written_event() const
Definition: sc_fifo.h:101
void sc_trace(sc_trace_file *tf, const sc_in< T > &port, const std::string &name)
virtual void update()
Definition: sc_fifo.h:340
virtual int num_free() const
Definition: sc_fifo.h:114
int m_num_readable
Definition: sc_fifo.h:166
#define SC_KERNEL_EVENT_PREFIX
Definition: sc_event.h:327
virtual void dump(::std::ostream &=::std::cout) const
Definition: sc_fifo.h:322
void trace(sc_trace_file *tf) const
Definition: sc_fifo.h:292