Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / model / vendor / TLM-2006-11-29 / tlm / tlm_annotated / tlm_annotated_channels / tlm_annotated_fifo.h
CommitLineData
86530b38
AT
1\r
2#ifndef TLM_ANNOTATED_FIFO_HEADER\r
3#define TLM_ANNOTATED_FIFO_HEADER\r
4\r
5#include "tlm_core.h"\r
6#include "tlm_annotated/tlm_annotated_ifs/tlm_annotated_ifs.h"\r
7#include "tlm_annotated/tlm_annotated_channels/tlm_peq.h"\r
8\r
9using analysis::analysis_port;\r
10using analysis::analysis_if;\r
11\r
12using tlm_core::tlm_fifo;\r
13using tlm_core::tlm_tag;\r
14\r
15\r
16template< typename T >\r
17class tlm_internal_annotated_fifo : \r
18public tlm_fifo<T> ,\r
19 public virtual analysis_if<T> ,\r
20 public virtual analysis_if< tlm_tag< T > * > {\r
21 \r
22 public:\r
23 typedef tlm_tag<T> *my_tag_ptr;\r
24\r
25 tlm_internal_annotated_fifo( const char *nm , int size ) :\r
26 tlm_fifo<T>( nm , size ) {}\r
27\r
28 void write( const T &t ) {\r
29 assert( nb_can_put( (my_tag_ptr)0 ) );\r
30 nb_put( t );\r
31 }\r
32 \r
33 void write( const my_tag_ptr & ) {\r
34 read_event( (my_tag_ptr)0 ).notify( SC_ZERO_TIME );\r
35 }\r
36 \r
37};\r
38\r
39//\r
40// From the put point of view, delayed puts are immediate. The transaction T is\r
41// considered to be in the fifo from the time at which nb_put( T , t ) was\r
42// called.\r
43//\r
44// However, from the get point of view, the effect of the delayed put is not\r
45// seen until t has expired. We cannot see the new data on the get side until\r
46// time t.\r
47//\r
48// The same rules apply to a delayed get : a get( T , t ) gets T immediately,\r
49// but the put side does not see the extra space in the fifo until time t.\r
50//\r
51// In summary : put->put and get->get is immediate, but put->get and get->put\r
52// are delayed.\r
53//\r
54// Although the precise effects of put and get may vary from channel to channel\r
55// these observability rules are part of the definition of the annotated\r
56// interfaces.\r
57//\r
58\r
59template< typename T >\r
60class tlm_annotated_fifo :\r
61public sc_module ,\r
62public virtual tlm_annotated_put_if< T > ,\r
63public virtual tlm_annotated_get_peek_if < T > {\r
64\r
65 public:\r
66\r
67 tlm_annotated_fifo( sc_module_name nm , int size = 1 ) :\r
68 sc_module( nm ) ,\r
69 m_size( size ) ,\r
70 m_fifo("internal_fifo" , size ) ,\r
71 m_put_peq("put_peq") ,\r
72 m_get_peq("pop_peq") {\r
73\r
74 m_put_peq.ap( m_fifo );\r
75 m_get_peq.ap( m_fifo );\r
76\r
77 }\r
78\r
79 tlm_annotated_fifo( int size = 1 ) :\r
80 sc_module( sc_gen_unique_name("annotated_fifo") ) ,\r
81 m_size( size ) ,\r
82 m_fifo("internal_fifo" , size ) ,\r
83 m_put_peq("put_peq") ,\r
84 m_get_peq("pop_peq") {\r
85\r
86 m_put_peq.ap( m_fifo );\r
87 m_get_peq.ap( m_fifo );\r
88\r
89 }\r
90 // non annotated nb_can_* methods\r
91\r
92 bool nb_can_put( tlm_tag<T> *t = 0 ) const {\r
93 return m_fifo.nb_can_put( m_put_peq.size() + m_get_peq.size() + 1 );\r
94 }\r
95\r
96 bool nb_can_get( tlm_tag<T> *t = 0 ) const {\r
97 return m_fifo.nb_can_get();\r
98 }\r
99\r
100 bool nb_can_peek( tlm_tag<T> *t = 0 ) const {\r
101 return m_fifo.nb_can_peek();\r
102 }\r
103\r
104 //\r
105 // annotated nb_can_* methods\r
106 //\r
107 // these are virtual because we may want to add some additional time based\r
108 // restrictions re: what can can be put and popped when : for example, we \r
109 // might want to insist that we only ever post to the end of both peqs, to \r
110 // preserve the ordering of the transactions.\r
111 //\r
112\r
113 // nb_can_put is part of the annotated non blocking put interface\r
114 \r
115 virtual bool nb_can_put( const sc_time &time , tlm_tag<T> *t = 0 ) const {\r
116 return nb_can_put();\r
117 }\r
118 \r
119 virtual bool nb_can_get( const sc_time &time , tlm_tag<T> *t = 0 ) const {\r
120 return nb_can_get();\r
121 }\r
122\r
123 // ok_to_* methods \r
124\r
125 const sc_event &ok_to_put( tlm_tag<T> *t = 0 ) const {\r
126 return m_fifo.ok_to_put();\r
127 }\r
128\r
129 const sc_event &ok_to_get( tlm_tag<T> *t = 0 ) const {\r
130 return m_fifo.ok_to_get();\r
131 }\r
132\r
133 const sc_event &ok_to_peek( tlm_tag<T> *t = 0 ) const {\r
134 return m_fifo.ok_to_peek();\r
135 }\r
136 \r
137 // non annotated nonblocking put, get + peek\r
138 \r
139 bool nb_put( const T &t ) {\r
140\r
141 if( !nb_can_put() ) {\r
142 return false;\r
143 }\r
144 \r
145 assert( m_fifo.nb_can_put() );\r
146 m_fifo.nb_put( t );\r
147 return true;\r
148\r
149 }\r
150 \r
151 bool nb_get( T &t ) {\r
152\r
153 if( !nb_can_get() ) {\r
154 return false;\r
155 }\r
156 \r
157 assert( m_fifo.nb_can_get() );\r
158 m_fifo.nb_get( t );\r
159 return true;\r
160\r
161 }\r
162\r
163 bool nb_peek( T &t ) const {\r
164 return m_fifo.nb_peek( t );\r
165 }\r
166\r
167 // annotated nonblocking methods\r
168\r
169 \r
170 bool nb_put( const T &transaction , const sc_time &time ) {\r
171\r
172 if( !nb_can_put( time ) ) {\r
173 return false;\r
174 }\r
175 \r
176 m_put_peq.write( transaction , time );\r
177 return true;\r
178\r
179 }\r
180\r
181 virtual bool nb_get( T &transaction , const sc_time &time ) {\r
182 static tlm_tag<T> *t;\r
183\r
184 if( !m_fifo.nb_get_no_notify( transaction ) ) {\r
185 return false;\r
186 }\r
187\r
188 m_get_peq.write( t , time );\r
189 return true;\r
190\r
191 }\r
192 \r
193 // blocking put, get and peek\r
194\r
195 void put( const T &t ) {\r
196 while( !nb_put( t ) ) {\r
197 wait( ok_to_put() );\r
198 }\r
199 }\r
200\r
201 T get( tlm_tag<T> *t = 0 ) {\r
202\r
203 T trans;\r
204\r
205 while( !nb_get( trans ) ) {\r
206 wait( ok_to_get() );\r
207 }\r
208\r
209 return trans;\r
210 }\r
211\r
212 T peek( tlm_tag<T> *t = 0 ) const {\r
213 return m_fifo.peek();\r
214 }\r
215\r
216 int size() { return m_size; }\r
217\r
218 private:\r
219 int m_size;\r
220\r
221 protected: // to allow for overriding of annotated can_put and can_get\r
222\r
223 tlm_internal_annotated_fifo<T> m_fifo;\r
224\r
225 tlm_peq<T> m_put_peq;\r
226 tlm_peq< tlm_tag<T> *> m_get_peq;\r
227\r
228};\r
229#endif\r