-
Notifications
You must be signed in to change notification settings - Fork 40
/
Copy pathsct_ipc_if.h
603 lines (520 loc) · 20.3 KB
/
sct_ipc_if.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
/******************************************************************************
* Copyright (c) 2023, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception.
*
*****************************************************************************/
/*
* Single Source library. Interfaces, general templates and defines.
*
* Author: Mikhail Moiseev
*/
#ifndef SCT_IPC_IF_H
#define SCT_IPC_IF_H
// Use sequential methods instead clocked threads in SS channels cycle accurate mode
//#define SCT_SEQ_METH
#include <systemc.h>
namespace sct {
/// Simulation mode (could be specified in CMakeLists.txt):
/// 0 -- cycle accurate, used for debug and SystemVerilog RTL synthesis
/// 1 -- approximate time, used for fast simulation and integration into VP
#ifdef SCT_TLM_MODE
static const bool SCT_CMN_TLM_MODE = 1;
#else
static const bool SCT_CMN_TLM_MODE = 0;
#endif
/// Intel Compiler for SystemC requires cycle accurate mode
#ifdef SCT_TLM_MODE
#ifdef __SC_TOOL__
static_assert (false, "DO NOT run Intel Compiler for SystemC in TLM mode");
#endif
#endif
#ifdef DEBUG_SYSTEMC
#ifdef __SC_TOOL__
static_assert (false, "DO NOT run Intel Compiler for SystemC with DEBUG_SYSTEMC");
#endif
#endif
/// Clock and reset traits:
/// clock 0 -- negedge, 1 -- posedge, 2 -- both edges
/// reset 0 -- active low, 1 -- active high
struct SCT_POSEDGE_NEGRESET {
static constexpr unsigned CLOCK = 1;
static constexpr bool RESET = 0;
};
struct SCT_POSEDGE_POSRESET {
static constexpr unsigned CLOCK = 1;
static constexpr bool RESET = 1;
};
struct SCT_NEGEDGE_NEGRESET {
static constexpr unsigned CLOCK = 0;
static constexpr bool RESET = 0;
};
struct SCT_NEGEDGE_POSRESET {
static constexpr unsigned CLOCK = 0;
static constexpr bool RESET = 1;
};
struct SCT_BOTHEDGES_POSRESET {
static constexpr unsigned CLOCK = 2;
static constexpr bool RESET = 1;
};
struct SCT_BOTHEDGES_NEGRESET {
static constexpr unsigned CLOCK = 2;
static constexpr bool RESET = 0;
};
/// Default traits for project modules (could be specified in CMakeLists.txt)
/// It is possible to redefine for individual modules
#ifndef SCT_CMN_TRAITS
#define SCT_CMN_TRAITS SCT_POSEDGE_NEGRESET
#endif
//=============================================================================
/// Put interface for Initiator and FIFO
template<class T, unsigned N = 1>
struct sct_put_if : virtual public sc_interface
{
static_assert (N <= 64, "N should be not great than 64");
static const unsigned long long ALL_ENABLED = ~0ULL;
/// Ready to put request, can be used in SCT_ASSERT
virtual bool ready() const = 0;
/// Reset put request in THREAD reset section and METHOD everywhere
virtual void reset_put() = 0;
/// Clear put request in METHOD and THREAD after reset
virtual void clear_put() = 0;
/// Non-blocking put request into FIFO/Initiator if it is ready
/// \param data -- request data
/// \param mask -- enable put or specify targets in multi-cast put
/// \return ready to request
virtual bool put(const T& data) = 0;
virtual bool put(const T& data, sc_uint<N> mask) = 0;
/// May-blocking put, can be used in THREAD only
/// \param data -- request data
virtual void b_put(const T& data) = 0;
/// Add put related signal to process sensitivity, use operator << instead
virtual void addTo(sc_sensitive& s) = 0;
virtual void addTo(sc_sensitive* s, sc_process_handle* p) = 0;
};
/// Get interface for Target and FIFO
/// Return value by constant reference to speed up simulation
template<class T>
struct sct_get_if : virtual public sc_interface
{
/// Request can be taken, can be used in SCT_ASSERT
virtual bool request() const = 0;
/// Reset get ready in THREAD reset section and METHOD everywhere
virtual void reset_get() = 0;
/// Clear get ready in METHOD or THREAD after reset
virtual void clear_get() = 0;
/// Return current request data, no change of the request
/// \return current request data, if no request returns last request data
virtual T peek() const = 0;
/// Non-blocking get request data and remove the request
/// \return current request data, if no request returns last request data
virtual T get() = 0;
/// Non-blocking get request data and remove the request if @enable is true
/// \param data -- current request data returned
/// \param enable -- remove request
/// \return true if there is a request
virtual bool get(T& data, bool enable = true) = 0;
/// May-blocking get, can be used in THREAD only
virtual T b_get() = 0;
/// Add get/request related signal to process sensitivity, use operator << instead
virtual void addTo(sc_sensitive& s) = 0;
virtual void addTo(sc_sensitive* s, sc_process_handle* p) = 0;
/// Add peek/request to process sensitivity, used in addition to @addTo()
virtual void addPeekTo(sc_sensitive& s) = 0;
};
/// FIFO specific interface
template<class T>
struct sct_fifo_if : public sct_put_if<T>, public sct_get_if<T>
{
/// FIFO size (number of slots), can be used in SCT_ASSERT
virtual unsigned size() const = 0;
/// Number of elements in FIFO (less or equal to size), can be used in SCT_ASSERT
/// \return value updated last clock edge for METHOD, last DC for THREAD
virtual unsigned elem_num() const = 0;
/// FIFO has (size()-N) elements or more
/// \return value updated last clock edge for METHOD, last DC for THREAD
virtual bool almost_full(const unsigned& N = 0) const = 0;
/// FIFO has N elements or less
/// \return value updated last clock edge for METHOD, last DC for THREAD
virtual bool almost_empty(const unsigned& N = 0) const = 0;
/// Bind clock and reset to FIFO, required in sct_target
virtual void clk_nrst(sc_in_clk& clk_in, sc_in<bool>& nrst_in) = 0;
/// Add FIFO signals to process sensitivity
virtual void addTo(sc_sensitive& s) = 0;
virtual void addToPut(sc_sensitive& s) = 0;
virtual void addToPut(sc_sensitive* s, sc_process_handle* p) = 0;
virtual void addToGet(sc_sensitive& s) = 0;
virtual void addToGet(sc_sensitive* s, sc_process_handle* p) = 0;
};
/// Input port interface
template <class T>
struct sct_in_if : virtual public sc_interface
{
virtual const T& read() const = 0;
virtual void addTo(sc_sensitive* s, sc_process_handle* p, sc_in_clk* c) {}
};
/// Output port interface
template <class T>
struct sct_inout_if : public sct_in_if<T>
{
virtual void write(const T& val) = 0;
};
/// Clock interface to get period
struct sct_clock_if : virtual public sc_interface
{
virtual const sc_time& period() const = 0;
};
//==============================================================================
/// Clock input which current process is sensitive to, set by @SCT_THREAD macro
static sc_in_clk* sct_curr_clock = nullptr;
/// Get period of @sc_clock from @sc_clk_in bound to it
inline const sc_time& get_clk_period(sc_in_clk* clk_in)
{
if (auto* i = clk_in->get_interface()) {
if (auto* clk = dynamic_cast<sct_clock_if*>(i)) {
//cout << " get_clk_period (sct_clock) " << clk_in->name() << " " << clk->period() << "\n";
return clk->period();
} else
if (auto* clk = dynamic_cast<sc_clock*>(i)) {
//cout << " get_clk_period (sc_clock) " << clk_in->name() << " " << clk->period() << "\n";
return clk->period();
}
}
std::cout << "No clock period taken from sc_in_clk: " << clk_in->name() << "\n";
assert (false);
return SC_ZERO_TIME;
}
/// Last sequential process handle for SCT_METHOD macros
static sc_process_handle sct_seq_proc_handle;
/// Method process macros, @SC_METHOD for combinational and sequential
/// Combinational method
#define SCT_METHOD1(proc) SC_METHOD(proc)
//==============================================================================
#ifdef SCT_TLM_MODE
/// Sequential method with SYNC reset
#define SCT_METHOD2(proc, clk) \
SC_METHOD(proc); \
sct_seq_proc_handle = sc_get_current_process_handle();
/// Sequential method with ASYNC reset
#define SCT_METHOD3(proc, clk, rst) \
SC_METHOD(proc); \
sct_seq_proc_handle = sc_get_current_process_handle();
/// Reset callback for @SCT_THREAD macro, used in approximate time mode only
struct sct_reset_callback {
sc_event* m_event;
sc_in_clk* m_clk;
sc_time m_period{SC_ZERO_TIME};
inline sct_reset_callback(sc_event* event, sc_in_clk* clk) :
m_event(event), m_clk(clk) {}
inline void operator () () {
if (m_period == SC_ZERO_TIME) {
m_period = get_clk_period(m_clk);
}
m_event->notify(m_period);
//cout << sc_time_stamp() << " " << sc_delta_count() << " callback " << m_period << " ("<< m_clk->name() << ")" << endl;
}
};
/// Reset callback storage <reset input port, callback>
static std::unordered_map<size_t, sct_reset_callback*> sct_reset_stor;
/// Thread process macro if it is sensitive to SS signals/ports only
/// @sct_signal/@sct_in/@sct_out get clock period from @sct_curr_clock
/// Spawn method provides reset event with @sct_reset_callback
#define SCT_THREAD3(proc, clk, rst) \
{ \
sct_reset_callback* callback; \
auto i = sct_reset_stor.find((size_t)&rst); \
if (i != sct_reset_stor.end()) { \
callback = i->second; \
if (callback->m_clk != &clk) { \
std::cout << "Different clock inputs for same reset " \
<< rst.name() << " not supported\n"; \
assert (false); \
} \
} else { \
sc_spawn_options edge_options; \
edge_options.spawn_method(); \
edge_options.dont_initialize(); \
edge_options.set_sensitivity(&rst.value_changed()); \
callback = new sct_reset_callback(new sc_event("e"), &clk); \
sc_spawn(*callback, sc_gen_unique_name("reset_callback"), &edge_options); \
sct_reset_stor.emplace((size_t)&rst, callback); \
} \
SC_THREAD(proc); \
this->sensitive << *(callback->m_event); \
sct_curr_clock = &clk; \
}
/// Thread process macro if it is sensitive to channels and SS signals/ports
/// @sct_signal/@sct_in/@sct_out get clock period from @sct_curr_clock
#define SCT_THREAD2(proc, clk) \
SC_THREAD(proc); \
sct_curr_clock = &clk;
#else
/// Sequential method with SYNC reset
#define SCT_METHOD2(proc, clk) \
SC_METHOD(proc); \
sct_seq_proc_handle = sc_get_current_process_handle(); \
if (SCT_CMN_TRAITS::CLOCK == 1) { \
this->sensitive << clk.pos(); \
} else \
if (SCT_CMN_TRAITS::CLOCK == 0) { \
this->sensitive << clk.neg(); \
} else { \
assert (false && "Both edge clock is not supported for sequential method"); \
}
/// Sequential method with ASYNC reset
#define SCT_METHOD3(proc, clk, rst) \
SC_METHOD(proc); \
sct_seq_proc_handle = sc_get_current_process_handle(); \
if (SCT_CMN_TRAITS::CLOCK == 1) { \
this->sensitive << clk.pos(); \
} else \
if (SCT_CMN_TRAITS::CLOCK == 0) { \
this->sensitive << clk.neg(); \
} else { \
assert (false && "Both edge clock is not supported for sequential method"); \
} \
if (SCT_CMN_TRAITS::RESET) { \
this->sensitive << rst.pos(); \
} else { \
this->sensitive << rst.neg(); \
}
#define SCT_THREAD3(proc, clk, rst) \
SC_THREAD(proc); \
if (SCT_CMN_TRAITS::CLOCK == 1) { \
this->sensitive << clk.pos(); \
} else \
if (SCT_CMN_TRAITS::CLOCK == 0) { \
this->sensitive << clk.neg(); \
} else { \
this->sensitive << clk; \
}
#define SCT_THREAD2(proc, clk) SCT_THREAD3(proc, clk, )
#endif
//==============================================================================
/// Method combinational and sequential process macros
#define SCT_METHOD(...) SCT_GET_MACRO(__VA_ARGS__, , SCT_METHOD3,\
SCT_METHOD2, SCT_METHOD1)(__VA_ARGS__)
/// Default thread process
#define SCT_THREAD1(proc) SC_THREAD(proc)
/// Macro argument number overload
#ifndef SCT_GET_MACRO
#define SCT_GET_MACRO(_1,_2,_3,_4,NAME,...) NAME
#endif
#define SCT_THREAD(...) SCT_GET_MACRO(__VA_ARGS__, , SCT_THREAD3,\
SCT_THREAD2, SCT_THREAD1)(__VA_ARGS__)
/// Clocked thread process macro with clock traits, used in cycle accurate mode
#define SCT_CTHREAD3(proc, clk, clock_mode) \
if (clock_mode == 1) { \
SC_CTHREAD(proc, clk.pos()); \
} else \
if (clock_mode == 0) { \
SC_CTHREAD(proc, clk.neg()); \
} else { \
SC_THREAD(proc); sensitive << clk; \
}
#define SCT_CTHREAD2(proc, clk) SCT_CTHREAD3(proc, clk, SCT_CMN_TRAITS::CLOCK);
#define SCT_CTHREAD(...) SCT_GET_MACRO(__VA_ARGS__, , SCT_CTHREAD3,\
SCT_CTHREAD2, )(__VA_ARGS__)
/// Bind Verilog DUT target/initiator to SystemC TB initiator/target channel
/// for multi-language simulation
#ifdef SCT_TLM_MODE
#define SCT_BIND_CHANNEL3(dut_module, dut_channel, tb_channel) \
static_assert (false, "DO NOT use SCT_BIND_CHANNEL macro in TLM mode");
#define SCT_BIND_CHANNEL4(dut_module, dut_channel, tb_channel, size) \
static_assert (false, "DO NOT use SCT_BIND_CHANNEL macro in TLM mode");
#else
#define SCT_BIND_CHANNEL3(dut_module, dut_channel, tb_channel) \
tb_channel.bind_rtl(dut_module.dut_channel##_core_req, tb_channel.core_req); \
tb_channel.bind_rtl(dut_module.dut_channel##_core_data, tb_channel.core_data); \
tb_channel.bind_rtl(dut_module.dut_channel##_core_ready, tb_channel.core_ready);
// Reverse order in Verilog port array
#define SCT_BIND_CHANNEL4(dut_module, dut_channel, tb_channel, size) \
for (unsigned i = 0; i != size; ++i) { \
tb_channel[i].bind_rtl(*dut_module.dut_channel##_core_req[size-1-i], tb_channel[i].core_req); \
tb_channel[i].bind_rtl(*dut_module.dut_channel##_core_data[size-1-i], tb_channel[i].core_data); \
tb_channel[i].bind_rtl(*dut_module.dut_channel##_core_ready[size-1-i], tb_channel[i].core_ready); \
}
#endif
#define SCT_BIND_CHANNEL(...) SCT_GET_MACRO(__VA_ARGS__, SCT_BIND_CHANNEL4, \
SCT_BIND_CHANNEL3, , )(__VA_ARGS__)
//==============================================================================
/// General initiator and target templates
template<
class T, class TRAITS = SCT_CMN_TRAITS,
bool TLM_MODE = SCT_CMN_TLM_MODE>
class sct_initiator
{};
template<
class T, class TRAITS = SCT_CMN_TRAITS,
bool TLM_MODE = SCT_CMN_TLM_MODE>
class sct_target
{};
/// General template for combinational target, ALWAYS_READY = 1
template<
class T, class TRAITS = SCT_CMN_TRAITS,
bool TLM_MODE = SCT_CMN_TLM_MODE>
class sct_comb_target
{};
/// General template for multi-initiator/multi-target/arbiter-target
/// Implementation is not available in open-source yet
template<
class T, unsigned N, class TRAITS = SCT_CMN_TRAITS,
bool TLM_MODE = SCT_CMN_TLM_MODE>
class sct_multi_target
{};
template<
class T, unsigned N, class TRAITS = SCT_CMN_TRAITS,
bool TLM_MODE = SCT_CMN_TLM_MODE>
class sct_multi_initiator
{};
template<
class T, unsigned N, class TRAITS = SCT_CMN_TRAITS,
bool TLM_MODE = SCT_CMN_TLM_MODE>
class sct_arbiter_target
{};
/// Empty base class for multi target/initiator
/// Implementation is not available in open-source yet
class sct_multi_target_base
{};
class sct_multi_initiator_base
{};
class sct_arbiter_target_base
{};
/// Target peek helper
template<class T, class TRAITS, bool TLM_MODE>
struct sct_target_peek{
sct_target<T, TRAITS, TLM_MODE>* target;
};
/// Multi-target peek helper
template<class T, unsigned N, class TRAITS, bool TLM_MODE>
struct sct_multi_target_peek{
sct_multi_target<T, N, TRAITS, TLM_MODE>* target;
};
/// FIFO general template
template<
class T, unsigned LENGTH, class TRAITS = SCT_CMN_TRAITS,
bool TLM_MODE = SCT_CMN_TLM_MODE>
class sct_fifo
{};
/// FIFO put/get helpers
template <typename T, unsigned LENGTH, class TRAITS, bool TLM_MODE>
struct sct_fifo_put{
sct_fifo<T, LENGTH, TRAITS, TLM_MODE>* fifo;
};
template <typename T, unsigned LENGTH, class TRAITS, bool TLM_MODE>
struct sct_fifo_get{
sct_fifo<T, LENGTH, TRAITS, TLM_MODE>* fifo;
};
template <typename T, unsigned LENGTH, class TRAITS, bool TLM_MODE>
struct sct_fifo_peek{
sct_fifo<T, LENGTH, TRAITS, TLM_MODE>* fifo;
};
#ifndef __SC_TOOL__
// Buffer declaration
template <typename T, unsigned LENGTH, class TRAITS>
class sct_buffer;
/// Buffer put/get helpers
template<
class T, unsigned LENGTH, class TRAITS = SCT_CMN_TRAITS>
struct sct_buffer_put {
sct_buffer<T, LENGTH, TRAITS>* buf;
};
template<
class T, unsigned LENGTH, class TRAITS = SCT_CMN_TRAITS>
struct sct_buffer_get {
sct_buffer<T, LENGTH, TRAITS>* buf;
};
template<
class T, unsigned LENGTH, class TRAITS = SCT_CMN_TRAITS>
struct sct_buffer_peek {
sct_buffer<T, LENGTH, TRAITS>* buf;
};
#endif
/// Pipe general template
template <
class T, /// Data type
unsigned N, /// Number of pipeline registers, one or more
class TRAITS = SCT_CMN_TRAITS,
bool TLM_MODE = SCT_CMN_TLM_MODE
>
class sct_pipe {};
/// Pipe put/get helpers
template <typename T, unsigned N, class TRAITS, bool TLM_MODE>
struct sct_pipe_put{
sct_pipe<T, N, TRAITS, TLM_MODE>* pipe;
};
template <typename T, unsigned N, class TRAITS, bool TLM_MODE>
struct sct_pipe_get{
sct_pipe<T, N, TRAITS, TLM_MODE>* pipe;
};
template <typename T, unsigned N, class TRAITS, bool TLM_MODE>
struct sct_pipe_peek{
sct_pipe<T, N, TRAITS, TLM_MODE>* pipe;
};
/// Register general template
template<
class T, class TRAITS = SCT_CMN_TRAITS,
bool TLM_MODE = SCT_CMN_TLM_MODE>
class sct_register {};
/// Clock and reset traits:
/// LEVEL -- signal level to generate events
struct SCT_ENABLE_HIGH {
static constexpr bool LEVEL = 1;
};
struct SCT_ENABLE_LOW {
static constexpr bool LEVEL = 0;
};
/// Input and output port general templates
/// ENABLE_EVENT -- if not @void generate events for sensitive thread process
/// every clock period if signal value corresponded to @LEVEL
template<
class T, class ENABLE_EVENT = void, bool TLM_MODE = SCT_CMN_TLM_MODE>
class sct_in {};
template<
class T, class ENABLE_EVENT = void, bool TLM_MODE = SCT_CMN_TLM_MODE>
class sct_out {};
/// Signal general template
/// ENABLE_EVENT -- if not @void generate events for sensitive thread process
/// every clock period if signal value corresponded to @LEVEL
template<
class T, class ENABLE_EVENT = void, bool TLM_MODE = SCT_CMN_TLM_MODE>
class sct_signal {};
/// Default enable signal and ports
using sct_enable_signal = sct_signal<bool, SCT_ENABLE_HIGH, SCT_CMN_TLM_MODE>;
using sct_enable_in = sct_in<bool, SCT_ENABLE_HIGH, SCT_CMN_TLM_MODE>;
using sct_enable_out = sct_out<bool, SCT_ENABLE_HIGH, SCT_CMN_TLM_MODE>;
/// Flip-Flop Synchronizer Cell Wrapper
/// SyncType: 1 - single msff, 2 - double msff, 3 - triple msff
/// RstVal: reset value
/// Implementation is not available in open-source yet
template <unsigned SyncType = 2, bool RstVal = 0,
class TRAITS = SCT_CMN_TRAITS, bool TLM_MODE = SCT_CMN_TLM_MODE>
class sct_ff_synchronizer
{};
/// Clock general template
template<
bool TLM_MODE = SCT_CMN_TLM_MODE>
class sct_clock {};
} // namespace sct
//=============================================================================
namespace sc_core {
/// Check if process is THREAD or CTHREAD
inline bool sct_is_thread_proc() {
#ifdef __SC_TOOL__
return false;
#else
auto procKind = sc_get_current_process_handle().proc_kind();
return (procKind == SC_THREAD_PROC_ || procKind == SC_CTHREAD_PROC_);
#endif
}
/// Check if process is METHOD
inline bool sct_is_method_proc() {
#ifdef __SC_TOOL__
return false;
#else
auto procKind = sc_get_current_process_handle().proc_kind();
return (procKind == SC_METHOD_PROC_);
#endif
}
} // namespace sc_core
#endif /* SCT_IPC_IF_H */