Skip to content

Commit d22e19a

Browse files
Version 1.6.12. Minor fixes in compiler and single source library
1 parent b2adcbf commit d22e19a

15 files changed

+348
-105
lines changed

components/common/sctcommon/sct_buffer.h

+117-23
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,19 @@ class sct_buffer :
5252
explicit sct_buffer(const char* name,
5353
bool sync_valid = 0, bool sync_ready = 0,
5454
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())
5657
{
5758
static_assert (LENGTH > 0);
5859
// This implementation equals to async valid/ready FIFO
5960
assert (!sync_valid && !sync_ready &&
60-
"No sync valid/ready allowed for Buffer");
61+
"No sync valid/ready allowed for Buffer");
6162
}
6263

63-
public:
64+
public:
65+
// No @event notified after exit from reset, the processes should be
66+
// waken up by another channel
67+
6468
bool ready() const override {
6569
return (element_num != LENGTH);
6670
}
@@ -78,7 +82,7 @@ class sct_buffer :
7882

7983
/// Call in METHOD everywhere and CTHREAD reset sections
8084
void reset_put() override {
81-
push_indx = 0;
85+
push_indx = 0;
8286
put_req = 0; data_in = T{};
8387
element_num = 0;
8488

@@ -117,6 +121,7 @@ class sct_buffer :
117121
if (element_num != 0) {
118122
get_req = 1;
119123
request_update();
124+
if constexpr (SCT_CMN_TLM_MODE) event.notify(clk_period);
120125
}
121126
return data_out;
122127
}
@@ -127,6 +132,7 @@ class sct_buffer :
127132
if (element_num != 0) {
128133
get_req = enable;
129134
request_update();
135+
if constexpr (SCT_CMN_TLM_MODE) event.notify(clk_period);
130136
return enable;
131137
} else {
132138
return false;
@@ -137,6 +143,7 @@ class sct_buffer :
137143
while (element_num == 0) wait();
138144
get_req = 1;
139145
request_update();
146+
if constexpr (SCT_CMN_TLM_MODE) event.notify(clk_period);
140147
return data_out;
141148
}
142149

@@ -145,17 +152,19 @@ class sct_buffer :
145152
if (element_num != LENGTH) {
146153
put_req = 1;
147154
request_update();
155+
if constexpr (SCT_CMN_TLM_MODE) event.notify(clk_period);
148156
return true;
149157
} else {
150158
return false;
151159
}
152160
}
153161

154162
bool put(const T& data, sc_uint<1> mask) override {
155-
data_in = data;
163+
data_in = data;
156164
if (element_num != LENGTH) {
157165
put_req = bool(mask);
158166
request_update();
167+
if constexpr (SCT_CMN_TLM_MODE) event.notify(clk_period);
159168
return mask;
160169
} else {
161170
return false;
@@ -167,6 +176,7 @@ class sct_buffer :
167176
while (element_num == LENGTH) wait();
168177
put_req = 1;
169178
request_update();
179+
if constexpr (SCT_CMN_TLM_MODE) event.notify(clk_period);
170180
}
171181

172182
/// Maximal number of elements
@@ -190,6 +200,13 @@ class sct_buffer :
190200
}
191201

192202
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+
193210
T buffer[LENGTH];
194211

195212
/// Index of element that will be poped
@@ -205,6 +222,8 @@ class sct_buffer :
205222
bool get_req;
206223
T data_out;
207224

225+
sc_event event;
226+
208227
void update() {
209228
if (get_req) {
210229
pop_indx = (pop_indx == LENGTH-1) ? 0 : (pop_indx+1);
@@ -220,34 +239,102 @@ class sct_buffer :
220239
data_out = buffer[pop_indx];
221240
}
222241

242+
void end_of_elaboration() override {
243+
if (!attached_put || !attached_get) {
244+
cout << "\nBuffer " << 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 << "\nBuffer " << name() << " clock input is not bound" << endl;
253+
assert (false);
254+
}
255+
}
256+
}
257+
223258
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+
}
225262

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 {
228268
auto procKind = sc_get_current_process_handle().proc_kind();
229269
if (procKind != SC_THREAD_PROC_ && procKind != SC_CTHREAD_PROC_) {
230270
cout << "Buffer cannot be used in combinational method process" << endl;
231271
assert (false);
232272
}
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;
233290
}
234291
}
235292

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 {
238299
auto procKind = p->proc_kind();
239300
if (procKind != SC_THREAD_PROC_ && procKind != SC_CTHREAD_PROC_) {
240301
cout << "Buffer cannot be used in combinational method process" << endl;
241302
assert (false);
242303
}
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;
243321
}
244322
}
245323

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+
}
251338

252339
inline void print(::std::ostream& os) const override
253340
{
@@ -267,9 +354,9 @@ class sct_buffer :
267354
os << ::std::endl;
268355
}
269356

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};
273360
};
274361

275362
#else
@@ -304,19 +391,26 @@ operator << ( sc_sensitive& s,
304391

305392
template<class T, unsigned LENGTH, class TRAITS>
306393
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 )
309403
{
310-
buffer.buf->addTo(s);
404+
get.buf->addToGet(s);
311405
return s;
312406
}
313407

314408
template<class T, unsigned LENGTH, class TRAITS>
315409
sc_sensitive&
316410
operator << ( sc_sensitive& s,
317-
sct::sct_buffer_peek<T, LENGTH, TRAITS>& buffer )
411+
sct::sct_buffer_peek<T, LENGTH, TRAITS>& peek )
318412
{
319-
// Peek can be done from combinational method process, do nothing
413+
peek.buf->addPeekTo(s);
320414
return s;
321415
}
322416

components/common/sctcommon/sct_ipc_if.h

+41-13
Original file line numberDiff line numberDiff line change
@@ -250,13 +250,11 @@ static sc_process_handle sct_seq_proc_handle;
250250
/// Reset callback storage <reset input port, callback>
251251
static std::unordered_map<size_t, sct_reset_callback*> sct_reset_stor;
252252

253-
/// Thread process macro if it is sensitive to signals only
253+
/// Thread process macro if it is sensitive to SS signals/ports only
254+
/// @sct_signal/@sct_in/@sct_out get clock period from @sct_curr_clock
255+
/// Spawn method provides reset event with @sct_reset_callback
254256
#define SCT_THREAD3(proc, clk, rst) \
255257
{ \
256-
sc_spawn_options edge_options; \
257-
edge_options.spawn_method(); \
258-
edge_options.dont_initialize(); \
259-
edge_options.set_sensitivity(&rst.value_changed()); \
260258
sct_reset_callback* callback; \
261259
auto i = sct_reset_stor.find((size_t)&rst); \
262260
if (i != sct_reset_stor.end()) { \
@@ -267,6 +265,10 @@ static sc_process_handle sct_seq_proc_handle;
267265
assert (false); \
268266
} \
269267
} else { \
268+
sc_spawn_options edge_options; \
269+
edge_options.spawn_method(); \
270+
edge_options.dont_initialize(); \
271+
edge_options.set_sensitivity(&rst.value_changed()); \
270272
callback = new sct_reset_callback(new sc_event("e"), &clk); \
271273
sc_spawn(*callback, sc_gen_unique_name("reset_callback"), &edge_options); \
272274
sct_reset_stor.emplace((size_t)&rst, callback); \
@@ -276,7 +278,8 @@ static sc_process_handle sct_seq_proc_handle;
276278
sct_curr_clock = &clk; \
277279
}
278280

279-
/// Thread process macro if it is sensitive to signals and channels
281+
/// Thread process macro if it is sensitive to channels and SS signals/ports
282+
/// @sct_signal/@sct_in/@sct_out get clock period from @sct_curr_clock
280283
#define SCT_THREAD2(proc, clk) \
281284
SC_THREAD(proc); \
282285
sct_curr_clock = &clk;
@@ -335,8 +338,8 @@ static sc_process_handle sct_seq_proc_handle;
335338
#define SCT_METHOD(...) SCT_GET_MACRO(__VA_ARGS__, , SCT_METHOD3,\
336339
SCT_METHOD2, SCT_METHOD1)(__VA_ARGS__)
337340

338-
/// Use default clock input name
339-
#define SCT_THREAD1(proc) SCT_THREAD2(proc, clk);
341+
/// Default thread process
342+
#define SCT_THREAD1(proc) SC_THREAD(proc)
340343

341344
/// Macro argument number overload
342345
#ifndef SCT_GET_MACRO
@@ -478,13 +481,20 @@ class sct_buffer;
478481
/// Buffer put/get helpers
479482
template<
480483
class T, unsigned LENGTH, class TRAITS = SCT_CMN_TRAITS>
481-
struct sct_buffer_sens {
484+
struct sct_buffer_put {
485+
sct_buffer<T, LENGTH, TRAITS>* buf;
486+
};
487+
template<
488+
class T, unsigned LENGTH, class TRAITS = SCT_CMN_TRAITS>
489+
struct sct_buffer_get {
482490
sct_buffer<T, LENGTH, TRAITS>* buf;
483491
};
484492

485493
template<
486494
class T, unsigned LENGTH, class TRAITS = SCT_CMN_TRAITS>
487-
struct sct_buffer_peek {};
495+
struct sct_buffer_peek {
496+
sct_buffer<T, LENGTH, TRAITS>* buf;
497+
};
488498
#endif
489499

490500
/// Pipe general template
@@ -516,19 +526,37 @@ template<
516526
bool TLM_MODE = SCT_CMN_TLM_MODE>
517527
class sct_register {};
518528

529+
/// Clock and reset traits:
530+
/// LEVEL -- signal level to generate events
531+
struct SCT_ENABLE_HIGH {
532+
static constexpr bool LEVEL = 1;
533+
};
534+
struct SCT_ENABLE_LOW {
535+
static constexpr bool LEVEL = 0;
536+
};
537+
519538
/// Input and output port general templates
539+
/// ENABLE_EVENT -- if not @void generate events for sensitive thread process
540+
/// every clock period if signal value corresponded to @LEVEL
520541
template<
521-
class T, bool TLM_MODE = SCT_CMN_TLM_MODE>
542+
class T, class ENABLE_EVENT = void, bool TLM_MODE = SCT_CMN_TLM_MODE>
522543
class sct_in {};
523544
template<
524-
class T, bool TLM_MODE = SCT_CMN_TLM_MODE>
545+
class T, class ENABLE_EVENT = void, bool TLM_MODE = SCT_CMN_TLM_MODE>
525546
class sct_out {};
526547

527548
/// Signal general template
549+
/// ENABLE_EVENT -- if not @void generate events for sensitive thread process
550+
/// every clock period if signal value corresponded to @LEVEL
528551
template<
529-
class T, bool TLM_MODE = SCT_CMN_TLM_MODE>
552+
class T, class ENABLE_EVENT = void, bool TLM_MODE = SCT_CMN_TLM_MODE>
530553
class sct_signal {};
531554

555+
/// Default enable signal and ports
556+
using sct_enable_signal = sct_signal<bool, SCT_ENABLE_HIGH, SCT_CMN_TLM_MODE>;
557+
using sct_enable_in = sct_in<bool, SCT_ENABLE_HIGH, SCT_CMN_TLM_MODE>;
558+
using sct_enable_out = sct_out<bool, SCT_ENABLE_HIGH, SCT_CMN_TLM_MODE>;
559+
532560
/// Flip-Flop Synchronizer Cell Wrapper
533561
/// SyncType: 1 - single msff, 2 - double msff, 3 - triple msff
534562
/// RstVal: reset value

0 commit comments

Comments
 (0)