TLM-2.0  2.0.3
Accellera TLM-2.0 proof-of-concept library
tlm_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 #ifndef __TLM_FIFO_H__
19 #define __TLM_FIFO_H__
20 
21 //
22 // This implements put, get and peek
23 //
24 // It also implements 0 and infinite size fifos - but the size
25 // zero fifos aren't rendezvous like zero length fifos, they simply are both
26 // full and empty at the same time.
27 //
28 // The size can be dynamically changed using the resize interface
29 //
30 // To get an infinite fifo use a -ve size in the constructor.
31 // The absolute value of the size is taken as the starting size of the
32 // actual physical buffer.
33 //
34 
35 //#include <systemc>
36 
39 
40 namespace tlm {
41 
42 template <typename T>
43 class tlm_fifo :
44  public virtual tlm_fifo_get_if<T>,
45  public virtual tlm_fifo_put_if<T>,
47 {
48 public:
49 
50  // constructors
51 
52  explicit tlm_fifo( int size_ = 1 )
53  : sc_core::sc_prim_channel( sc_core::sc_gen_unique_name( "fifo" ) ) {
54 
55  init( size_ );
56 
57  }
58 
59  explicit tlm_fifo( const char* name_, int size_ = 1 )
60  : sc_core::sc_prim_channel( name_ ) {
61 
62  init( size_ );
63 
64  }
65 
66  // destructor
67 
68  virtual ~tlm_fifo() {}
69 
70  // tlm get interface
71 
72  T get( tlm_tag<T> * = 0 );
73 
74  bool nb_get( T& );
75  bool nb_can_get( tlm_tag<T> * = 0 ) const;
76  const sc_core::sc_event &ok_to_get( tlm_tag<T> * = 0 ) const {
77  return m_data_written_event;
78  }
79 
80  // tlm peek interface
81 
82  T peek( tlm_tag<T> * = 0 ) const;
83 
84  bool nb_peek( T& ) const;
85  bool nb_can_peek( tlm_tag<T> * = 0 ) const;
86  const sc_core::sc_event &ok_to_peek( tlm_tag<T> * = 0 ) const {
87  return m_data_written_event;
88  }
89 
90  // tlm put interface
91 
92  void put( const T& );
93 
94  bool nb_put( const T& );
95  bool nb_can_put( tlm_tag<T> * = 0 ) const;
96 
97  const sc_core::sc_event& ok_to_put( tlm_tag<T> * = 0 ) const {
98  return m_data_read_event;
99  }
100 
101  // resize if
102 
103  void nb_expand( unsigned int n = 1 );
104  void nb_unbound( unsigned int n = 16 );
105 
106  bool nb_reduce( unsigned int n = 1 );
107  bool nb_bound( unsigned int n );
108 
109  // debug interface
110 
111  bool nb_peek( T & , int n ) const;
112  bool nb_poke( const T & , int n = 0 );
113 
114  int used() const {
115  return m_num_readable - m_num_read;
116  }
117 
118  int size() const {
119  return m_size;
120  }
121 
122  void debug() const {
123 
124  if( is_empty() ) std::cout << "empty" << std::endl;
125  if( is_full() ) std::cout << "full" << std::endl;
126 
127  std::cout << "size " << size() << " - " << used() << " used "
128  << std::endl;
129  std::cout << "readable " << m_num_readable
130  << std::endl;
131  std::cout << "written/read " << m_num_written << "/" << m_num_read
132  << std::endl;
133 
134  }
135 
136  // support functions
137 
138  static const char* const kind_string;
139 
140  const char* kind() const
141  { return kind_string; }
142 
143 
144 protected:
146  return m_data_read_event;
147  }
148 
149 protected:
150 
151  void update();
152 
153  // support methods
154 
155  void init( int );
156 
157 protected:
158 
160 
161  int m_size; // logical size of fifo
162 
163  int m_num_readable; // #samples readable
164  int m_num_read; // #samples read during this delta cycle
165  int m_num_written; // #samples written during this delta cycle
166  bool m_expand; // has an expand occurred during this delta cycle ?
167  int m_num_read_no_notify; // #samples read without notify during this delta cycle
168 
171 
172 private:
173 
174  // disabled
175  tlm_fifo( const tlm_fifo<T>& );
176  tlm_fifo& operator = ( const tlm_fifo<T>& );
177 
178  //
179  // use nb_can_get() and nb_can_put() rather than the following two
180  // private functions
181  //
182 
183  bool is_empty() const {
184  return used() == 0;
185  }
186 
187  bool is_full() const {
188  //return size() == m_num_readable + m_num_written; // Old buggy code
189  if( size() < 0 )
190  return false;
191  else
192  return size() <= m_num_readable + m_num_written;
193  }
194 
195 };
196 
197 template <typename T>
198 const char* const tlm_fifo<T>::kind_string = "tlm_fifo";
199 
200 
201 /******************************************************************
202 //
203 // init and update
204 //
205 ******************************************************************/
206 
207 template< typename T >
208 inline
209 void
210 tlm_fifo<T>::init( int size_ ) {
211 
212  if( size_ > 0 ) {
213  buffer.resize( size_ );
214  }
215 
216  else if( size_ < 0 ) {
217  buffer.resize( -size_ );
218  }
219 
220  else {
221  buffer.resize( 16 );
222  }
223 
224  m_size = size_;
225  m_num_readable = 0;
226  m_num_read = 0;
227  m_num_written = 0;
228  m_expand = false;
229  m_num_read_no_notify = false;
230 
231 }
232 
233 template < typename T>
234 inline
235 void
237 {
238  if( m_num_read > m_num_read_no_notify || m_expand ) {
239  m_data_read_event.notify( sc_core::SC_ZERO_TIME );
240  }
241 
242  if( m_num_written > 0 ) {
243  m_data_written_event.notify( sc_core::SC_ZERO_TIME );
244  }
245 
246  m_expand = false;
247  m_num_read = 0;
248  m_num_written = 0;
249  m_num_readable = buffer.used();
250  m_num_read_no_notify = 0;
251 
252 }
253 
254 } // namespace tlm
255 
259 
260 #endif
261 
circular_buffer< T > buffer
Definition: tlm_fifo.h:159
bool m_expand
Definition: tlm_fifo.h:166
bool nb_reduce(unsigned int n=1)
void nb_expand(unsigned int n=1)
bool nb_bound(unsigned int n)
sc_core::sc_event m_data_read_event
Definition: tlm_fifo.h:169
bool nb_can_peek(tlm_tag< T > *=0) const
Definition: tlm_fifo_peek.h:75
void put(const T &)
void debug() const
Definition: tlm_fifo.h:122
const sc_core::sc_event & ok_to_get(tlm_tag< T > *=0) const
Definition: tlm_fifo.h:76
T peek(tlm_tag< T > *=0) const
Definition: tlm_fifo_peek.h:26
bool nb_can_put(tlm_tag< T > *=0) const
const char * kind() const
Definition: tlm_fifo.h:140
int size() const
Definition: tlm_fifo.h:118
const char * sc_gen_unique_name(const char *, bool preserve_first)
bool nb_poke(const T &, int n=0)
Definition: tlm_fifo_peek.h:83
int m_num_read_no_notify
Definition: tlm_fifo.h:167
int m_num_written
Definition: tlm_fifo.h:165
tlm_fifo(int size_=1)
Definition: tlm_fifo.h:52
void nb_unbound(unsigned int n=16)
void update()
Definition: tlm_fifo.h:236
const sc_core::sc_event & ok_to_put(tlm_tag< T > *=0) const
Definition: tlm_fifo.h:97
bool nb_get(T &)
int m_num_read
Definition: tlm_fifo.h:164
const sc_time SC_ZERO_TIME
bool nb_put(const T &)
sc_core::sc_event & read_event(tlm_tag< T > *=0)
Definition: tlm_fifo.h:145
static const char *const kind_string
Definition: tlm_fifo.h:138
bool nb_peek(T &) const
Definition: tlm_fifo_peek.h:43
int used() const
Definition: tlm_fifo.h:114
void init(int)
Definition: tlm_fifo.h:210
const sc_core::sc_event & ok_to_peek(tlm_tag< T > *=0) const
Definition: tlm_fifo.h:86
virtual ~tlm_fifo()
Definition: tlm_fifo.h:68
tlm_fifo(const char *name_, int size_=1)
Definition: tlm_fifo.h:59
sc_core::sc_event m_data_written_event
Definition: tlm_fifo.h:170
bool nb_can_get(tlm_tag< T > *=0) const
int m_num_readable
Definition: tlm_fifo.h:163