@@ -39,24 +39,17 @@ class sct_buffer :
39
39
public sct_fifo_if<T>
40
40
{
41
41
public:
42
- // / Initialize FIFO slots in reset with zeros
43
- const bool INIT_BUFFER;
44
-
45
- // / Number of bits in variables store index and length of FIFO
46
- static const unsigned INDX_WIDTH = sct_addrbits1<LENGTH>;
47
- using Indx_t = sc_uint<INDX_WIDTH>;
48
- static const unsigned ELEM_NUM_WIDTH = sct_nbits<LENGTH>;
49
- using ElemNum_t = sc_uint<ELEM_NUM_WIDTH>;
50
-
51
- // / \param init_buffer -- Initialize all buffer elements with zeros in reset
52
- // / First element to get is always initialized to zero id
53
42
explicit sct_buffer (const char * name,
54
43
bool sync_valid = 0 , bool sync_ready = 0 ,
55
44
bool use_elem_num = 0 , bool init_buffer = 0 ) :
56
- sc_prim_channel(name), INIT_BUFFER(init_buffer),
45
+ sc_prim_channel(name),
46
+ put_req(false ), get_req(false ), pop_indx(0 ), push_indx(0 ), element_num(0 ),
47
+ #ifdef DEBUG_SYSTEMC
48
+ attached_put (false ), attached_get(false ),
49
+ #endif
57
50
event (std::string(std::string(name)+" _event" ).c_str())
58
51
{
59
- static_assert (LENGTH > 0 );
52
+ assert (LENGTH > 0 );
60
53
// This implementation equals to async valid/ready FIFO
61
54
assert (!sync_valid && !sync_ready &&
62
55
" No sync valid/ready allowed for Buffer" );
@@ -77,23 +70,16 @@ class sct_buffer :
77
70
// / Call in METHOD everywhere and CTHREAD reset sections
78
71
void reset_get () override {
79
72
pop_indx = 0 ;
80
- get_req = 0 ; data_out = T{};
73
+ get_req = 0 ;
81
74
request_update ();
82
75
}
83
76
84
77
// / Call in METHOD everywhere and CTHREAD reset sections
85
78
void reset_put () override {
86
79
push_indx = 0 ;
87
- put_req = 0 ; data_in = T{};
80
+ put_req = 0 ;
88
81
element_num = 0 ;
89
-
90
- // Initialize zero cell to provide zero data before first push
91
82
buffer[0 ] = T{};
92
- if (INIT_BUFFER) {
93
- for (unsigned i = 1 ; i != LENGTH; i++) {
94
- buffer[i] = T{};
95
- }
96
- }
97
83
request_update ();
98
84
}
99
85
@@ -114,70 +100,66 @@ class sct_buffer :
114
100
}
115
101
116
102
T peek () const override {
117
- return data_out;
103
+ return buffer[pop_indx];
104
+ }
105
+
106
+ protected:
107
+ inline void doGet () {
108
+ get_req = 1 ;
109
+ request_update ();
118
110
}
119
111
112
+ inline void doPut (const T& data) {
113
+ put_req = 1 ;
114
+ buffer[push_indx] = data;
115
+ request_update ();
116
+ }
117
+
118
+ public:
120
119
// / \return current request data, if no request last data returned
121
120
T get () override {
122
- if (element_num != 0 ) {
123
- get_req = 1 ;
124
- request_update ();
125
- if constexpr (SCT_CMN_TLM_MODE) event.notify (clk_period);
126
- }
127
- return data_out;
121
+ if (element_num != 0 ) { doGet (); }
122
+ return buffer[pop_indx];
128
123
}
129
124
130
125
// / \return true if request is valid and enable is true
131
126
bool get (T& data, bool enable = true ) override {
132
- data = data_out;
133
- if (element_num != 0 ) {
134
- get_req = enable;
135
- request_update ();
136
- if constexpr (SCT_CMN_TLM_MODE) event.notify (clk_period);
137
- return enable;
127
+ data = buffer[pop_indx];
128
+ if (enable && element_num != 0 ) {
129
+ doGet ();
130
+ return true ;
138
131
} else {
139
132
return false ;
140
133
}
141
134
}
142
135
143
136
T b_get () override {
144
137
while (element_num == 0 ) wait ();
145
- get_req = 1 ;
146
- request_update ();
147
- if constexpr (SCT_CMN_TLM_MODE) event.notify (clk_period);
148
- return data_out;
138
+ doGet ();
139
+ return buffer[pop_indx];
149
140
}
150
141
151
142
bool put (const T& data) override {
152
- data_in = data;
153
143
if (element_num != LENGTH) {
154
- put_req = 1 ;
155
- request_update ();
156
- if constexpr (SCT_CMN_TLM_MODE) event.notify (clk_period);
144
+ doPut (data);
157
145
return true ;
158
146
} else {
159
147
return false ;
160
148
}
161
149
}
162
150
163
151
bool put (const T& data, sc_uint<1 > mask) override {
164
- data_in = data;
165
- if (element_num != LENGTH) {
166
- put_req = bool (mask);
167
- request_update ();
168
- if constexpr (SCT_CMN_TLM_MODE) event.notify (clk_period);
169
- return mask;
152
+ if (mask && element_num != LENGTH) {
153
+ doPut (data);
154
+ return true ;
170
155
} else {
171
156
return false ;
172
157
}
173
158
}
174
159
175
160
void b_put (const T& data) override {
176
- data_in = data;
177
161
while (element_num == LENGTH) wait ();
178
- put_req = 1 ;
179
- request_update ();
180
- if constexpr (SCT_CMN_TLM_MODE) event.notify (clk_period);
162
+ doPut (data);
181
163
}
182
164
183
165
// / Maximal number of elements
@@ -201,28 +183,26 @@ class sct_buffer :
201
183
}
202
184
203
185
protected:
204
- // / This buffer attached to a processes
205
- bool attached_put = false ;
206
- bool attached_get = false ;
207
-
208
- sc_in_clk* clk_in = nullptr ;
209
- sc_time clk_period = SC_ZERO_TIME;
210
-
211
- T buffer[LENGTH];
212
-
213
186
// / Index of element that will be poped
214
- Indx_t pop_indx ;
187
+ unsigned short pop_indx : 16 ;
215
188
// / Index where pushed element will be stored
216
- Indx_t push_indx ;
189
+ unsigned short push_indx : 16 ;
217
190
// / Number of elements
218
- ElemNum_t element_num ;
191
+ unsigned short element_num : 16 ;
219
192
220
- bool put_req;
221
- T data_in;
193
+ bool put_req : 8 ;
194
+ bool get_req : 8 ;
195
+
196
+ #ifdef DEBUG_SYSTEMC
197
+ bool attached_put : 8 ;
198
+ bool attached_get : 8 ;
199
+ #endif
222
200
223
- bool get_req ;
224
- T data_out ;
201
+ sc_in_clk* clk_in = nullptr ;
202
+ sc_time clk_period = SC_ZERO_TIME ;
225
203
204
+ T buffer[LENGTH] = {};
205
+
226
206
// / Event for put, get and peek thread processes notification
227
207
sc_event event;
228
208
@@ -233,20 +213,21 @@ class sct_buffer :
233
213
get_req = 0 ;
234
214
}
235
215
if (put_req) {
236
- buffer[push_indx] = data_in;
237
216
push_indx = (push_indx == LENGTH-1 ) ? 0 : (push_indx+1 );
238
217
element_num += 1 ;
239
218
put_req = 0 ;
240
219
}
241
- data_out = buffer[pop_indx] ;
220
+ if constexpr (SCT_CMN_TLM_MODE) event. notify (clk_period) ;
242
221
}
243
222
244
223
void end_of_elaboration () override {
224
+ #ifdef DEBUG_SYSTEMC
245
225
if (!attached_put || !attached_get) {
246
226
cout << " \n Buffer " << name ()
247
227
<< " is not fully attached to process(es)" << endl;
248
228
assert (false );
249
229
}
230
+ #endif
250
231
if constexpr (SCT_CMN_TLM_MODE) {
251
232
if (clk_in) {
252
233
clk_period = get_clk_period (clk_in);
@@ -259,23 +240,32 @@ class sct_buffer :
259
240
260
241
public:
261
242
void clk_nrst (sc_in_clk& clk_in_, sc_in<bool >& nrst_in) {
262
- if constexpr (SCT_CMN_TLM_MODE) { clk_in = &clk_in_; }
243
+ clk_in = &clk_in_;
263
244
}
264
245
265
246
void add_to (sc_sensitive& s, bool attachedPut, bool attachedGet) {
266
247
if (sct_seq_proc_handle == sc_get_current_process_handle ()) {
267
248
// Sequential method
268
- if constexpr (SCT_CMN_TLM_MODE) { s << event; }
249
+ if constexpr (SCT_CMN_TLM_MODE) {
250
+ s << event;
251
+ } else {
252
+ if (TRAITS::CLOCK == 2 ) s << *clk_in;
253
+ else s << (TRAITS::CLOCK ? clk_in->pos () : clk_in->neg ());
254
+ }
269
255
} else {
270
256
auto procKind = sc_get_current_process_handle ().proc_kind ();
271
257
if (procKind != SC_THREAD_PROC_ && procKind != SC_CTHREAD_PROC_) {
272
258
cout << " Buffer cannot be used in combinational method process" << endl;
273
259
assert (false );
274
260
}
275
- if constexpr (SCT_CMN_TLM_MODE) {
261
+ if constexpr (SCT_CMN_TLM_MODE) {
276
262
if (procKind != SC_CTHREAD_PROC_) { s << event; }
277
- }
263
+ } else {
264
+ if (TRAITS::CLOCK == 2 ) s << *clk_in;
265
+ else s << (TRAITS::CLOCK ? clk_in->pos () : clk_in->neg ());
266
+ }
278
267
}
268
+ #ifdef DEBUG_SYSTEMC
279
269
if (attachedPut) {
280
270
if (attached_put) {
281
271
cout << " Double addToPut() for Buffer: " << name () << endl;
@@ -290,13 +280,19 @@ class sct_buffer :
290
280
}
291
281
attached_get = true ;
292
282
}
283
+ #endif
293
284
}
294
285
295
286
void add_to (sc_sensitive* s, sc_process_handle* p, bool attachedPut,
296
287
bool attachedGet) {
297
288
if (sct_seq_proc_handle == *p) {
298
289
// Sequential method
299
- if constexpr (SCT_CMN_TLM_MODE) { *s << *p << event; }
290
+ if constexpr (SCT_CMN_TLM_MODE) {
291
+ *s << *p << event;
292
+ } else {
293
+ if (TRAITS::CLOCK == 2 ) *s << *p << *clk_in;
294
+ else *s << *p << (TRAITS::CLOCK ? clk_in->pos () : clk_in->neg ());
295
+ }
300
296
} else {
301
297
auto procKind = p->proc_kind ();
302
298
if (procKind != SC_THREAD_PROC_ && procKind != SC_CTHREAD_PROC_) {
@@ -305,8 +301,12 @@ class sct_buffer :
305
301
}
306
302
if constexpr (SCT_CMN_TLM_MODE) {
307
303
if (procKind != SC_CTHREAD_PROC_) { *s << *p << event; }
308
- }
304
+ } else {
305
+ if (TRAITS::CLOCK == 2 ) *s << *p << *clk_in;
306
+ else *s << *p << (TRAITS::CLOCK ? clk_in->pos () : clk_in->neg ());
307
+ }
309
308
}
309
+ #ifdef DEBUG_SYSTEMC
310
310
if (attachedPut) {
311
311
if (attached_put) {
312
312
cout << " Double addToPut() for Buffer: " << name () << endl;
@@ -321,6 +321,7 @@ class sct_buffer :
321
321
}
322
322
attached_get = true ;
323
323
}
324
+ #endif
324
325
}
325
326
326
327
void addTo (sc_sensitive& s) override { add_to (s, true , true ); }
0 commit comments