Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / model / vendor / TLM-2006-11-29 / tlm / tlm_core / tlm_fifo / circular_buffer.h
CommitLineData
86530b38
AT
1/*****************************************************************************\r
2\r
3 The following code is derived, directly or indirectly, from the SystemC\r
4 source code Copyright (c) 1996-2004 by all Contributors.\r
5 All Rights reserved.\r
6\r
7 The contents of this file are subject to the restrictions and limitations\r
8 set forth in the SystemC Open Source License Version 2.4 (the "License");\r
9 You may not use this file except in compliance with such restrictions and\r
10 limitations. You may obtain instructions on how to receive a copy of the\r
11 License at http://www.systemc.org/. Software distributed by Contributors\r
12 under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF\r
13 ANY KIND, either express or implied. See the License for the specific\r
14 language governing rights and limitations under the License.\r
15\r
16 *****************************************************************************/\r
17\r
18\r
19//\r
20// To the LRM writer : this class is purely an artifact of the implementation.\r
21//\r
22\r
23#ifndef CIRCULAR_BUFFER_HEADER\r
24#define CIRCULAR_BUFFER_HEADER\r
25\r
26#include <iostream>\r
27\r
28using std::cout;\r
29using std::endl;\r
30\r
31template < typename T >\r
32class circular_buffer\r
33{\r
34public:\r
35 circular_buffer( int size );\r
36\r
37 circular_buffer<T> &operator=( const circular_buffer<T> & ); \r
38\r
39 ~circular_buffer() { delete [] m_buf; }\r
40 \r
41 void resize( int size );\r
42\r
43 const T &read();\r
44 void write( const T & );\r
45\r
46 bool is_empty() const { return used() == 0; }\r
47 bool is_full() const { return free() == 0; }\r
48\r
49 int size() const { return m_size; }\r
50 int used() const { return m_used; }\r
51 int free() const { return m_free; }\r
52\r
53 T &write_data() { return m_buf[m_wi]; }\r
54 const T &read_data() const { return m_buf[m_ri]; }\r
55\r
56 const T &peek_data( int i ) const { return m_buf[(m_ri + i) % size()]; }\r
57 T &poke_data( int i ) { return m_buf[(m_ri + i) % size()]; }\r
58\r
59 void increment_write_pos( int i = 1 );\r
60 void increment_read_pos( int i = 1 );\r
61\r
62 void init();\r
63\r
64 void debug() const;\r
65\r
66private:\r
67 circular_buffer( const circular_buffer<T> &b ); // disabled\r
68 void copy( const circular_buffer<T> &b );\r
69\r
70private:\r
71 int m_size; // size of the buffer\r
72 T* m_buf; // the buffer\r
73 int m_free; // number of free spaces\r
74 int m_used; // number of used spaces\r
75 int m_ri; // index of next read\r
76 int m_wi; // index of next write\r
77 \r
78};\r
79\r
80template< typename T >\r
81void\r
82circular_buffer<T>::debug() const\r
83{\r
84\r
85 cout << "Buffer debug" << endl;\r
86 cout << "Size : " << size() << endl;\r
87 cout << "Free/Used " << free() << "/" << used() << endl;\r
88 cout << "Indeces : r/w = " << m_ri << "/" << m_wi << endl;\r
89\r
90 if( is_empty() ) {\r
91\r
92 cout << "empty" << endl;\r
93\r
94 }\r
95\r
96 if( is_full() ) {\r
97\r
98 cout << "full" << endl;\r
99\r
100 }\r
101\r
102 cout << "Data : " << endl;\r
103 for( int i = 0; i < used(); i++ ) {\r
104\r
105 cout << peek_data( i ) << endl;\r
106\r
107 }\r
108\r
109\r
110}\r
111\r
112template < typename T >\r
113circular_buffer<T>::\r
114circular_buffer( int size ) {\r
115\r
116 m_size = size;\r
117 m_buf = new T[m_size];\r
118\r
119 init();\r
120\r
121}\r
122 \r
123template < typename T >\r
124circular_buffer<T> &\r
125circular_buffer<T>::operator=( const circular_buffer<T> &b ) {\r
126\r
127 init();\r
128\r
129 for( int i = 0; i < size() && i < b.used(); i++ ) {\r
130\r
131 write( b.peek_data( i ) );\r
132\r
133 }\r
134\r
135 return *this;\r
136 \r
137}\r
138\r
139template < typename T >\r
140void\r
141circular_buffer<T>::resize( int size )\r
142{\r
143\r
144 int i;\r
145 T *new_buf = new T[size];\r
146\r
147 for( i = 0; i < size && i < used(); i++ ) {\r
148\r
149 new_buf[i] = peek_data( i );\r
150\r
151 }\r
152\r
153 delete [] m_buf;\r
154\r
155 m_size = size;\r
156 m_ri = 0;\r
157 m_wi = i % m_size;\r
158 m_used = i;\r
159 m_free = m_size - m_used;\r
160 \r
161 m_buf = new_buf;\r
162\r
163}\r
164 \r
165\r
166template < typename T >\r
167void\r
168circular_buffer<T>::init() {\r
169\r
170 m_free = m_size;\r
171 m_used = 0;\r
172 m_ri = 0;\r
173 m_wi = 0;\r
174\r
175}\r
176\r
177template < typename T >\r
178void\r
179circular_buffer<T>::copy( const circular_buffer<T> &b )\r
180{\r
181\r
182 m_size = b.m_size; // size of the buffer\r
183 m_buf = b.m_buf; // the buffer\r
184 m_free = b.m_free; // number of free spaces\r
185 m_used = b.m_used; // number of used spaces\r
186 m_ri = b.m_ri; // index of next read\r
187 m_wi = b.m_wi; // index of next write \r
188\r
189}\r
190\r
191template < typename T >\r
192const T &\r
193circular_buffer<T>::read()\r
194{\r
195\r
196 const T &t = read_data();\r
197\r
198 increment_read_pos();\r
199\r
200 return t;\r
201\r
202}\r
203\r
204template < typename T >\r
205void\r
206circular_buffer<T>::write( const T &t )\r
207{\r
208\r
209 write_data() = t;\r
210 increment_write_pos();\r
211\r
212}\r
213\r
214\r
215template < typename T >\r
216void\r
217circular_buffer<T>::increment_write_pos( int i ) {\r
218\r
219 m_wi = ( m_wi + i ) % m_size;\r
220 m_used += i;\r
221 m_free -= i;\r
222 \r
223}\r
224\r
225template < typename T >\r
226void\r
227circular_buffer<T>::increment_read_pos( int i ) {\r
228\r
229 m_ri = ( m_ri + i ) % m_size;\r
230 m_used -= i;\r
231 m_free += i;\r
232 \r
233}\r
234\r
235#endif\r
236\r