Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / model / vendor / TLM-2006-11-29 / tlm / tlm_core / tlm_fifo / tlm_fifo.h
CommitLineData
86530b38
AT
1
2/*****************************************************************************
3
4 The following code is derived, directly or indirectly, from the SystemC
5 source code Copyright (c) 1996-2004 by all Contributors.
6 All Rights reserved.
7
8 The contents of this file are subject to the restrictions and limitations
9 set forth in the SystemC Open Source License Version 2.4 (the "License");
10 You may not use this file except in compliance with such restrictions and
11 limitations. You may obtain instructions on how to receive a copy of the
12 License at http://www.systemc.org/. Software distributed by Contributors
13 under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
14 ANY KIND, either express or implied. See the License for the specific
15 language governing rights and limitations under the License.
16
17 *****************************************************************************/
18
19
20#ifndef TLM_FIFO_HEADER
21#define TLM_FIFO_HEADER
22
23//
24// This implements put, get and peek
25//
26// It also implements 0 and infinite size fifos - but the size
27// zero fifos aren't rendezvous like zero length fifos, they simply are both
28// full and empty at the same time.
29//
30// The size can be dynamically changed using the resize interface
31//
32// To get an infinite fifo use a -ve size in the constructor.
33// The absolute value of the size is taken as the starting size of the
34// actual physical buffer.
35//
36
37#include <systemc.h>
38
39#include "tlm_core/tlm_interfaces/tlm_fifo_ifs.h"
40#include "tlm_core/tlm_fifo/circular_buffer.h"
41
42
43
44template <class T>
45class tlm_fifo :
46 public virtual tlm_fifo_get_if<T>,
47 public virtual tlm_fifo_put_if<T>,
48 public sc_prim_channel
49{
50public:
51
52 // constructors
53
54 explicit tlm_fifo( int size_ = 1 )
55 : sc_prim_channel( sc_gen_unique_name( "fifo" ) ) {
56
57 init( size_ );
58
59 }
60
61 explicit tlm_fifo( const char* name_, int size_ = 1 )
62 : sc_prim_channel( name_ ) {
63
64 init( size_ );
65
66 }
67
68 // destructor
69
70 virtual ~tlm_fifo() {
71
72 if( buffer != 0 ) delete buffer;
73
74 }
75
76 // tlm get interface
77
78 T get( tlm_tag<T> *t = 0 );
79
80 bool nb_get( T& );
81 bool nb_can_get( tlm_tag<T> *t = 0 ) const;
82 const sc_event &ok_to_get( tlm_tag<T> *t = 0 ) const {
83 return m_data_written_event;
84 }
85
86 // tlm peek interface
87
88 T peek( tlm_tag<T> *t = 0 ) const;
89
90 bool nb_peek( T& ) const;
91 bool nb_can_peek( tlm_tag<T> *t = 0 ) const;
92 const sc_event &ok_to_peek( tlm_tag<T> *t = 0 ) const {
93 return m_data_written_event;
94 }
95
96 // tlm put interface
97
98 void put( const T& );
99
100 bool nb_put( const T& );
101 bool nb_can_put( tlm_tag<T> *t = 0 ) const;
102
103 const sc_event& ok_to_put( tlm_tag<T> *t = 0 ) const {
104 return m_data_read_event;
105 }
106
107 // resize if
108
109 void nb_expand( unsigned int n = 1 );
110 void nb_unbound( unsigned int n = 16 );
111
112 bool nb_reduce( unsigned int n = 1 );
113 bool nb_bound( unsigned int n );
114
115 // debug interface
116
117 bool nb_peek( T & , int n ) const;
118 bool nb_poke( const T & , int n = 0 );
119
120 int used() const {
121 return m_num_readable - m_num_read;
122 }
123
124 int size() const {
125 return m_size;
126 }
127
128 void debug() const {
129
130 if( is_empty() ) cout << "empty" << endl;
131 if( is_full() ) cout << "full" << endl;
132
133 cout << "size " << size() << " - " << used() << " used " << endl;
134 cout << "readable " << m_num_readable << endl;
135 cout << "written/read " << m_num_written << "/" << m_num_read << endl;
136
137 }
138
139 // support functions
140
141 static const char* const kind_string;
142
143 const char* kind() const
144 { return kind_string; }
145
146
147 friend class tlm_annotated::tlm_annotated_fifo<T>;
148
149private: // some methods to support tlm_annotated_fifo !
150
151 bool nb_can_put( int count , tlm_tag<T> *t = 0 ) const {
152 if( m_size < 0 ) {
153 return true;
154 }
155 return m_num_readable + m_num_written + count <= m_size;
156 }
157
158 bool nb_get_no_notify( T& );
159
160protected:
161 sc_event &read_event( tlm_tag<T> *t = 0 ) {
162 return m_data_read_event;
163 }
164
165protected:
166
167 void update();
168
169 // support methods
170
171 void init( int );
172
173protected:
174
175 circular_buffer<T> *buffer;
176
177 int m_size; // logical size of fifo
178
179 int m_num_readable; // #samples readable
180 int m_num_read; // #samples read during this delta cycle
181 int m_num_written; // #samples written during this delta cycle
182 bool m_expand; // has an expand occurred during this delta cycle ?
183 int m_num_read_no_notify; // #samples read without notify during this delta cycle
184
185 sc_event m_data_read_event;
186 sc_event m_data_written_event;
187
188private:
189
190 // disabled
191 tlm_fifo( const tlm_fifo<T>& );
192 tlm_fifo& operator = ( const tlm_fifo<T>& );
193
194 //
195 // use nb_can_get() and nb_can_put() rather than the following two
196 // private functions
197 //
198
199 bool is_empty() const {
200 return used() == 0;
201 }
202
203 bool is_full() const {
204 return size() == m_num_readable + m_num_written;
205 }
206
207};
208
209template <typename T>
210const char* const tlm_fifo<T>::kind_string = "tlm_fifo";
211
212
213/******************************************************************
214//
215// init and update
216//
217******************************************************************/
218
219template< typename T >
220inline
221void
222tlm_fifo<T>::init( int size_ ) {
223
224 if( size_ > 0 ) {
225 buffer = new circular_buffer<T>( size_);
226 }
227
228 else if( size_ < 0 ) {
229 buffer = new circular_buffer<T>( -size_ );
230 }
231
232 else {
233 buffer = new circular_buffer<T>( 16 );
234 }
235
236 m_size = size_;
237 m_num_readable = 0;
238 m_num_read = 0;
239 m_num_written = 0;
240 m_expand = false;
241 m_num_read_no_notify = false;
242
243}
244
245template < typename T>
246inline
247void
248tlm_fifo<T>::update()
249{
250 if( m_num_read > m_num_read_no_notify || m_expand ) {
251 m_data_read_event.notify( SC_ZERO_TIME );
252 }
253
254 if( m_num_written > 0 ) {
255 m_data_written_event.notify( SC_ZERO_TIME );
256 }
257
258 m_expand = false;
259 m_num_read = 0;
260 m_num_written = 0;
261 m_num_readable = buffer->used();
262 m_num_read_no_notify = 0;
263
264}
265
266#include "tlm_core/tlm_fifo/tlm_fifo_put_get.h"
267#include "tlm_core/tlm_fifo/tlm_fifo_peek.h"
268#include "tlm_core/tlm_fifo/tlm_fifo_resize.h"
269
270#endif
271