@@ -52,15 +52,19 @@ class sct_buffer :
52
52
explicit sct_buffer (const char * name,
53
53
bool sync_valid = 0 , bool sync_ready = 0 ,
54
54
bool use_elem_num = 0 , bool init_buffer = 0 ) :
55
- sc_prim_channel(name), INIT_BUFFER(init_buffer)
55
+ sc_prim_channel(name), INIT_BUFFER(init_buffer),
56
+ event(std::string(std::string(name)+"_event").c_str())
56
57
{
57
58
static_assert (LENGTH > 0 );
58
59
// This implementation equals to async valid/ready FIFO
59
60
assert (!sync_valid && !sync_ready &&
60
- " No sync valid/ready allowed for Buffer" );
61
+ " No sync valid/ready allowed for Buffer" );
61
62
}
62
63
63
- public:
64
+ public:
65
+ // No @event notified after exit from reset, the processes should be
66
+ // waken up by another channel
67
+
64
68
bool ready () const override {
65
69
return (element_num != LENGTH);
66
70
}
@@ -78,7 +82,7 @@ class sct_buffer :
78
82
79
83
// / Call in METHOD everywhere and CTHREAD reset sections
80
84
void reset_put () override {
81
- push_indx = 0 ;
85
+ push_indx = 0 ;
82
86
put_req = 0 ; data_in = T{};
83
87
element_num = 0 ;
84
88
@@ -117,6 +121,7 @@ class sct_buffer :
117
121
if (element_num != 0 ) {
118
122
get_req = 1 ;
119
123
request_update ();
124
+ if constexpr (SCT_CMN_TLM_MODE) event.notify (clk_period);
120
125
}
121
126
return data_out;
122
127
}
@@ -127,6 +132,7 @@ class sct_buffer :
127
132
if (element_num != 0 ) {
128
133
get_req = enable;
129
134
request_update ();
135
+ if constexpr (SCT_CMN_TLM_MODE) event.notify (clk_period);
130
136
return enable;
131
137
} else {
132
138
return false ;
@@ -137,6 +143,7 @@ class sct_buffer :
137
143
while (element_num == 0 ) wait ();
138
144
get_req = 1 ;
139
145
request_update ();
146
+ if constexpr (SCT_CMN_TLM_MODE) event.notify (clk_period);
140
147
return data_out;
141
148
}
142
149
@@ -145,17 +152,19 @@ class sct_buffer :
145
152
if (element_num != LENGTH) {
146
153
put_req = 1 ;
147
154
request_update ();
155
+ if constexpr (SCT_CMN_TLM_MODE) event.notify (clk_period);
148
156
return true ;
149
157
} else {
150
158
return false ;
151
159
}
152
160
}
153
161
154
162
bool put (const T& data, sc_uint<1 > mask) override {
155
- data_in = data;
163
+ data_in = data;
156
164
if (element_num != LENGTH) {
157
165
put_req = bool (mask);
158
166
request_update ();
167
+ if constexpr (SCT_CMN_TLM_MODE) event.notify (clk_period);
159
168
return mask;
160
169
} else {
161
170
return false ;
@@ -167,6 +176,7 @@ class sct_buffer :
167
176
while (element_num == LENGTH) wait ();
168
177
put_req = 1 ;
169
178
request_update ();
179
+ if constexpr (SCT_CMN_TLM_MODE) event.notify (clk_period);
170
180
}
171
181
172
182
// / Maximal number of elements
@@ -190,6 +200,13 @@ class sct_buffer :
190
200
}
191
201
192
202
protected:
203
+ // / This buffer attached to a processes
204
+ bool attached_put = false ;
205
+ bool attached_get = false ;
206
+
207
+ sc_in_clk* clk_in = nullptr ;
208
+ sc_time clk_period = SC_ZERO_TIME;
209
+
193
210
T buffer[LENGTH];
194
211
195
212
// / Index of element that will be poped
@@ -205,6 +222,8 @@ class sct_buffer :
205
222
bool get_req;
206
223
T data_out;
207
224
225
+ sc_event event;
226
+
208
227
void update () {
209
228
if (get_req) {
210
229
pop_indx = (pop_indx == LENGTH-1 ) ? 0 : (pop_indx+1 );
@@ -220,34 +239,102 @@ class sct_buffer :
220
239
data_out = buffer[pop_indx];
221
240
}
222
241
242
+ void end_of_elaboration () override {
243
+ if (!attached_put || !attached_get) {
244
+ cout << " \n Buffer " << name ()
245
+ << " is not fully attached to process(es)" << endl;
246
+ assert (false );
247
+ }
248
+ if constexpr (SCT_CMN_TLM_MODE) {
249
+ if (clk_in) {
250
+ clk_period = get_clk_period (clk_in);
251
+ } else {
252
+ cout << " \n Buffer " << name () << " clock input is not bound" << endl;
253
+ assert (false );
254
+ }
255
+ }
256
+ }
257
+
223
258
public:
224
- void clk_nrst (sc_in_clk& clk_in, sc_in<bool >& nrst_in) {}
259
+ void clk_nrst (sc_in_clk& clk_in_, sc_in<bool >& nrst_in) {
260
+ if constexpr (SCT_CMN_TLM_MODE) { clk_in = &clk_in_; }
261
+ }
225
262
226
- void addTo (sc_sensitive& s) override {
227
- if (sct_seq_proc_handle != sc_get_current_process_handle ()) {
263
+ void add_to (sc_sensitive& s, bool attachedPut, bool attachedGet) {
264
+ if (sct_seq_proc_handle == sc_get_current_process_handle ()) {
265
+ // Sequential method
266
+ if constexpr (SCT_CMN_TLM_MODE) { s << event; }
267
+ } else {
228
268
auto procKind = sc_get_current_process_handle ().proc_kind ();
229
269
if (procKind != SC_THREAD_PROC_ && procKind != SC_CTHREAD_PROC_) {
230
270
cout << " Buffer cannot be used in combinational method process" << endl;
231
271
assert (false );
232
272
}
273
+ if constexpr (SCT_CMN_TLM_MODE) {
274
+ if (procKind != SC_CTHREAD_PROC_) { s << event; }
275
+ }
276
+ }
277
+ if (attachedPut) {
278
+ if (attached_put) {
279
+ cout << " Double addToPut() for Buffer: " << name () << endl;
280
+ assert (false );
281
+ }
282
+ attached_put = true ;
283
+ }
284
+ if (attachedGet) {
285
+ if (attached_get) {
286
+ cout << " Double addToGet() for Buffer: " << name () << endl;
287
+ assert (false );
288
+ }
289
+ attached_get = true ;
233
290
}
234
291
}
235
292
236
- void addTo (sc_sensitive* s, sc_process_handle* p) override {
237
- if (sct_seq_proc_handle != *p) {
293
+ void add_to (sc_sensitive* s, sc_process_handle* p, bool attachedPut,
294
+ bool attachedGet) {
295
+ if (sct_seq_proc_handle == *p) {
296
+ // Sequential method
297
+ if constexpr (SCT_CMN_TLM_MODE) { *s << *p << event; }
298
+ } else {
238
299
auto procKind = p->proc_kind ();
239
300
if (procKind != SC_THREAD_PROC_ && procKind != SC_CTHREAD_PROC_) {
240
301
cout << " Buffer cannot be used in combinational method process" << endl;
241
302
assert (false );
242
303
}
304
+ if constexpr (SCT_CMN_TLM_MODE) {
305
+ if (procKind != SC_CTHREAD_PROC_) { *s << *p << event; }
306
+ }
307
+ }
308
+ if (attachedPut) {
309
+ if (attached_put) {
310
+ cout << " Double addToPut() for Buffer: " << name () << endl;
311
+ assert (false );
312
+ }
313
+ attached_put = true ;
314
+ }
315
+ if (attachedGet) {
316
+ if (attached_get) {
317
+ cout << " Double addToGet() for Buffer: " << name () << endl;
318
+ assert (false );
319
+ }
320
+ attached_get = true ;
243
321
}
244
322
}
245
323
246
- void addToPut (sc_sensitive& s) override { addTo (s); }
247
- void addToPut (sc_sensitive* s, sc_process_handle* p) override { addTo (s, p); }
248
- void addToGet (sc_sensitive& s) override { addTo (s); }
249
- void addToGet (sc_sensitive* s, sc_process_handle* p) override { addTo (s, p); }
250
- void addPeekTo (sc_sensitive& s) override {}
324
+ void addTo (sc_sensitive& s) override { add_to (s, true , true ); }
325
+ void addTo (sc_sensitive* s, sc_process_handle* p) override {
326
+ add_to (s, p, true , true ); }
327
+ void addToPut (sc_sensitive& s) override { add_to (s, true , false ); }
328
+ void addToPut (sc_sensitive* s, sc_process_handle* p) override {
329
+ add_to (s, p, true , false ); }
330
+ void addToGet (sc_sensitive& s) override { add_to (s, false , true ); }
331
+ void addToGet (sc_sensitive* s, sc_process_handle* p) override {
332
+ add_to (s, p, false , true ); }
333
+
334
+ void addPeekTo (sc_sensitive& s) override {
335
+ cout << " addPeekTo() for Buffer is not supported yet" << endl;
336
+ assert (false );
337
+ }
251
338
252
339
inline void print (::std::ostream& os) const override
253
340
{
@@ -267,9 +354,9 @@ class sct_buffer :
267
354
os << ::std::endl;
268
355
}
269
356
270
- sct_buffer_sens <T, LENGTH, TRAITS> PUT{this };
271
- sct_buffer_sens <T, LENGTH, TRAITS> GET{this };
272
- sct_buffer_peek<T, LENGTH, TRAITS> PEEK{};
357
+ sct_buffer_put <T, LENGTH, TRAITS> PUT{this };
358
+ sct_buffer_get <T, LENGTH, TRAITS> GET{this };
359
+ sct_buffer_peek<T, LENGTH, TRAITS> PEEK{this };
273
360
};
274
361
275
362
#else
@@ -304,19 +391,26 @@ operator << ( sc_sensitive& s,
304
391
305
392
template <class T , unsigned LENGTH, class TRAITS >
306
393
sc_sensitive&
307
- operator << ( sc_sensitive& s,
308
- sct::sct_buffer_sens<T, LENGTH, TRAITS>& buffer )
394
+ operator << ( sc_sensitive& s, sct::sct_buffer_put<T, LENGTH, TRAITS>& put )
395
+ {
396
+ put.buf ->addToPut (s);
397
+ return s;
398
+ }
399
+
400
+ template <class T , unsigned LENGTH, class TRAITS >
401
+ sc_sensitive&
402
+ operator << ( sc_sensitive& s, sct::sct_buffer_get<T, LENGTH, TRAITS>& get )
309
403
{
310
- buffer .buf ->addTo (s);
404
+ get .buf ->addToGet (s);
311
405
return s;
312
406
}
313
407
314
408
template <class T , unsigned LENGTH, class TRAITS >
315
409
sc_sensitive&
316
410
operator << ( sc_sensitive& s,
317
- sct::sct_buffer_peek<T, LENGTH, TRAITS>& buffer )
411
+ sct::sct_buffer_peek<T, LENGTH, TRAITS>& peek )
318
412
{
319
- // Peek can be done from combinational method process, do nothing
413
+ peek. buf -> addPeekTo (s);
320
414
return s;
321
415
}
322
416
0 commit comments