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