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