Skip to content

Commit 616c274

Browse files
Version 1.5.15. Join same states in always_comb block done, peek in TLM mode updated
1 parent 232806d commit 616c274

File tree

168 files changed

+2077
-3867
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

168 files changed

+2077
-3867
lines changed

components/common/sctcommon/sct_ipc_if.h

+26-3
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ struct sct_get_if : virtual public sc_interface
125125
/// Add get/request related signal to process sensitivity, use operator << instead
126126
virtual void addTo(sc_sensitive& s) = 0;
127127
virtual void addTo(sc_sensitive* s, sc_process_handle* p) = 0;
128-
/// Add peek/request related signal to process sensitivity
128+
/// Add peek/request to process sensitivity, used in addition to @addTo()
129129
virtual void addPeekTo(sc_sensitive& s) = 0;
130130
};
131131

@@ -300,7 +300,7 @@ static std::unordered_map<size_t, sct_reset_callback*> sct_reset_stor;
300300
/// Method process macro, same as SC_METHOD(...)
301301
#define SCT_METHOD(proc) SC_METHOD(proc)
302302

303-
/// Bind SV DUT target/initiator channel to SystemC TB initiator/target channel
303+
/// Bind Verilog DUT target/initiator to SystemC TB initiator/target channel
304304
/// for multi-language simulation
305305
#ifdef SCT_TLM_MODE
306306
#define SCT_BIND_CHANNEL3(dut_module, dut_channel, tb_channel) \
@@ -312,7 +312,7 @@ static std::unordered_map<size_t, sct_reset_callback*> sct_reset_stor;
312312
tb_channel.bind_rtl(dut_module.dut_channel##_core_req, tb_channel.core_req); \
313313
tb_channel.bind_rtl(dut_module.dut_channel##_core_data, tb_channel.core_data); \
314314
tb_channel.bind_rtl(dut_module.dut_channel##_core_ready, tb_channel.core_ready);
315-
// Reverse order in SV port array
315+
// Reverse order in Verilog port array
316316
#define SCT_BIND_CHANNEL4(dut_module, dut_channel, tb_channel, size) \
317317
for (unsigned i = 0; i != size; ++i) { \
318318
tb_channel[i].bind_rtl(*dut_module.dut_channel##_core_req[size-1-i], tb_channel[i].core_req); \
@@ -408,6 +408,29 @@ struct sct_fifo_peek{
408408
sct_fifo<T, LENGTH, TRAITS, TLM_MODE>* fifo;
409409
};
410410

411+
/// Pipe general template
412+
template <
413+
class T, /// Data type
414+
unsigned N, /// Number of pipeline registers, one or more
415+
class TRAITS = SCT_CMN_TRAITS,
416+
bool TLM_MODE = SCT_CMN_TLM_MODE
417+
>
418+
class sct_pipe {};
419+
420+
/// Pipe put/get helpers
421+
template <typename T, unsigned N, class TRAITS, bool TLM_MODE>
422+
struct sct_pipe_put{
423+
sct_pipe<T, N, TRAITS, TLM_MODE>* pipe;
424+
};
425+
template <typename T, unsigned N, class TRAITS, bool TLM_MODE>
426+
struct sct_pipe_get{
427+
sct_pipe<T, N, TRAITS, TLM_MODE>* pipe;
428+
};
429+
template <typename T, unsigned N, class TRAITS, bool TLM_MODE>
430+
struct sct_pipe_peek{
431+
sct_pipe<T, N, TRAITS, TLM_MODE>* pipe;
432+
};
433+
411434
/// Register general template
412435
template<
413436
class T, class TRAITS = SCT_CMN_TRAITS,

components/common/sctcommon/sct_prim_fifo.h

+95-26
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,20 @@ class sct_prim_fifo :
7979
bool sync_ready;
8080
const bool USE_ELEM_NUM;
8181

82-
bool cthread_put = false;
83-
bool cthread_get = false;
82+
bool cthread_put = false;
83+
bool cthread_get = false;
84+
bool cthread_peek = false;
8485

85-
sc_in_clk* clk_in = nullptr;
86+
/// FIFO used for Target/Initiator simulation
87+
bool targ_init = false;
88+
bool targ_init_sync = false;
89+
90+
sc_in_clk* clk_in = nullptr;
8691
sc_time clk_period = SC_ZERO_TIME;
8792

88-
sc_time GET_TIME = SC_ZERO_TIME;
89-
sc_time PUT_TIME = SC_ZERO_TIME;
93+
sc_time GET_TIME = SC_ZERO_TIME;
94+
sc_time PUT_TIME = SC_ZERO_TIME;
95+
sc_time PEEK_TIME = SC_ZERO_TIME;
9096

9197
sct_prim_signal<bool> has_reset{"has_reset"};
9298
sct_prim_signal<bool> put_req{"put_req"};
@@ -98,6 +104,8 @@ class sct_prim_fifo :
98104
sc_signal<unsigned> element_num{"element_num"};
99105
sc_signal<T> get_data{"get_data"};
100106
sc_signal<T> get_data_next{"get_data_next"};
107+
108+
sc_signal<bool> put_done{"put_done"}; // Auxiliary signal to meet RTL timing
101109

102110
bool hasReset= 0;
103111
unsigned getIndx = 0; // Index of element that will be get
@@ -114,6 +122,7 @@ class sct_prim_fifo :
114122

115123
sc_event put_event;
116124
sc_event get_event;
125+
sc_event* peek_event = nullptr;
117126
sc_event update_event;
118127

119128
/// Channel update, run at DC 0
@@ -159,14 +168,23 @@ class sct_prim_fifo :
159168
cout << "NOTIFIED update get " << name() << endl;
160169
#endif
161170
}
162-
171+
if (peek_event && (!cthread_peek || (doPut && sync_valid))) {
172+
peek_event->notify(PEEK_TIME);
173+
}
174+
163175
#ifdef NOTIFY_DEBUG
164176
//if (std::string(name()).find("tresp") != std::string::npos)
165177
cout << sc_time_stamp() << " " << sc_delta_count() << " updateProc "
166178
<< name() << " doPut|doGet " << doPut << doGet << " elemNum" << elemNum << endl;
167179
#endif
168180
}
169181

182+
if (targ_init_sync) {
183+
// To provide de-assert for @put_done
184+
if (!cthread_put && (doPut || doGet)) update_event.notify(clk_period);
185+
put_done = doPut || doGet;
186+
}
187+
170188
element_num = elemNum;
171189
get_data = buffer[getIndx];
172190
get_data_next = buffer[getIndx == fifoSize-1 ? 0 : getIndx+1];
@@ -178,8 +196,22 @@ class sct_prim_fifo :
178196

179197
/// Internal ready/valid/data functions equivalent to RTL logic
180198
inline bool putReady() const {
199+
// For Target/Initiator mode get required at almost full FIFO to allow put
200+
// cout << sc_time_stamp() << " " << sc_delta_count()
201+
// << " targ_init_sync " << targ_init_sync
202+
// << " put_done " << put_done
203+
// << " get_req == get_req_d " << (get_req == get_req_d)
204+
// << " put_req == put_req_d " << (put_req == put_req_d)
205+
// << " element_num " << element_num.read() << endl;
206+
207+
if (targ_init_sync && !cthread_put) {
208+
if (cthread_get && get_req != get_req_d) { return true; }
209+
if (!put_done && element_num.read() != 0) { return false; }
210+
}
211+
181212
return ((element_num.read() != fifoSize &&
182-
(!cthread_put || put_req == put_req_d ||
213+
(!cthread_put ||
214+
(targ_init ? get_req != get_req_d : put_req == put_req_d) ||
183215
element_num.read() != fifoSize-1)) ||
184216
(!sync_ready && get_req != get_req_d));
185217
}
@@ -201,8 +233,11 @@ class sct_prim_fifo :
201233
assert (clk_in && "clk_in is nullptr");
202234
clk_period = get_clk_period(clk_in);
203235

204-
GET_TIME = cthread_get ? clk_period : SC_ZERO_TIME;
205-
PUT_TIME = cthread_put ? clk_period : SC_ZERO_TIME;
236+
GET_TIME = cthread_get ? clk_period : SC_ZERO_TIME;
237+
PUT_TIME = cthread_put ? clk_period : SC_ZERO_TIME;
238+
PEEK_TIME = cthread_peek ? clk_period : SC_ZERO_TIME;
239+
240+
//cout << "PUT_TIME " << PUT_TIME << " GET_TIME " << GET_TIME << " PEEK_TIME " << PEEK_TIME << endl;
206241

207242
// Do not check @sync_valid and @sync_ready as prim_fifo could be used
208243
// as part of target/initiator in non-process context
@@ -222,6 +257,7 @@ class sct_prim_fifo :
222257
// Notify put/get processes at reset exit
223258
put_event.notify(PUT_TIME);
224259
get_event.notify(GET_TIME);
260+
if (peek_event) peek_event->notify(PEEK_TIME);
225261
}
226262
}
227263

@@ -233,11 +269,14 @@ class sct_prim_fifo :
233269
put_data = T{};
234270
}
235271

236-
if (!cthread_get && !cthread_put && !sync_valid && put_req != put_req_d) {
237-
get_event.notify(GET_TIME);
238-
#ifdef NOTIFY_DEBUG
239-
cout << "NOTIFIED reset_put() " << name() << endl;
240-
#endif
272+
if (!cthread_put && !sync_valid && put_req != put_req_d) {
273+
if (!cthread_get) {
274+
get_event.notify(GET_TIME);
275+
#ifdef NOTIFY_DEBUG
276+
cout << "NOTIFIED reset_put() " << name() << endl;
277+
#endif
278+
}
279+
if (peek_event && !cthread_peek) peek_event->notify(PEEK_TIME);
241280
}
242281
}
243282

@@ -246,11 +285,14 @@ class sct_prim_fifo :
246285
put_data = T{};
247286

248287
// Clear put notifies get process if both are methods
249-
if (!cthread_get && !cthread_put && !sync_valid && put_req != put_req_d) {
250-
get_event.notify(GET_TIME);
251-
#ifdef NOTIFY_DEBUG
252-
cout << "NOTIFIED clear_put() " << name() << endl;
253-
#endif
288+
if (!cthread_put && !sync_valid && put_req != put_req_d) {
289+
if (!cthread_get) {
290+
get_event.notify(GET_TIME);
291+
#ifdef NOTIFY_DEBUG
292+
cout << "NOTIFIED clear_put() " << name() << endl;
293+
#endif
294+
}
295+
if (peek_event && !cthread_peek) peek_event->notify(PEEK_TIME);
254296
}
255297
}
256298

@@ -303,9 +345,10 @@ class sct_prim_fifo :
303345
// If put() in thread and get makes FIFO empty, notifies get process
304346
// as this put() allows one more get
305347
if (!sync_valid && (USE_ELEM_NUM || element_num == 0 ||
306-
(cthread_put && get_req != get_req_d && element_num == 1)))
348+
(cthread_put && get_req != get_req_d && element_num == 1)))
307349
{
308350
get_event.notify(GET_TIME);
351+
if (peek_event) peek_event->notify(PEEK_TIME);
309352
#ifdef NOTIFY_DEBUG
310353
cout << "NOTIFIED put() " << name() << endl;
311354
#endif
@@ -314,7 +357,7 @@ class sct_prim_fifo :
314357
if (cthread_put) put_event.notify(PUT_TIME);
315358

316359
#ifdef SCT_TLM_DEBUG
317-
if (putTime == sc_time_stamp()) {
360+
if (cthread_put && putTime == sc_time_stamp()) {
318361
cout << sc_time_stamp() << " " << name() << ", ERROR: multiple put\n" << endl;
319362
sc_assert (false);
320363
}
@@ -337,6 +380,7 @@ class sct_prim_fifo :
337380
(cthread_put && get_req != get_req_d && element_num == 1)))
338381
{
339382
get_event.notify(GET_TIME);
383+
if (peek_event) peek_event->notify(PEEK_TIME);
340384
#ifdef NOTIFY_DEBUG
341385
cout << "NOTIFIED put() " << name() << endl;
342386
#endif
@@ -345,7 +389,7 @@ class sct_prim_fifo :
345389
if (cthread_put) put_event.notify(PUT_TIME);
346390

347391
#ifdef SCT_TLM_DEBUG
348-
if (putTime == sc_time_stamp()) {
392+
if (cthread_put && putTime == sc_time_stamp()) {
349393
cout << sc_time_stamp() << " " << name() << ", ERROR: multiple put\n" << endl;
350394
sc_assert (false);
351395
}
@@ -371,8 +415,12 @@ class sct_prim_fifo :
371415
// If @USE_ELEM_NUM every get notifies put process
372416
// If get() in thread and put makes FIFO full, notifies put process
373417
// as this get() allows one more put
418+
// For Target/Initiator mode notify at almost full FIFO to allow put
419+
374420
if (!sync_ready && (USE_ELEM_NUM || element_num == fifoSize ||
375-
(cthread_get && put_req != put_req_d && element_num == fifoSize-1)))
421+
(cthread_get && put_req != put_req_d && element_num == fifoSize-1) ||
422+
(targ_init && cthread_put && element_num == fifoSize-1) ||
423+
(targ_init_sync && !cthread_put && cthread_get) ))
376424
{
377425
put_event.notify(PUT_TIME);
378426
#ifdef NOTIFY_DEBUG
@@ -381,9 +429,10 @@ class sct_prim_fifo :
381429
}
382430
// Notify thread itself to allow next get
383431
if (cthread_get) get_event.notify(GET_TIME);
432+
if (peek_event && cthread_peek) peek_event->notify(PEEK_TIME);
384433

385434
#ifdef SCT_TLM_DEBUG
386-
if (getTime == sc_time_stamp()) {
435+
if (cthread_get && getTime == sc_time_stamp()) {
387436
cout << sc_time_stamp() << " " << name() << ", ERROR: multiple get\n" << endl;
388437
sc_assert (false);
389438
}
@@ -413,9 +462,10 @@ class sct_prim_fifo :
413462
}
414463
// Notify thread itself to allow next get
415464
if (cthread_get) get_event.notify(GET_TIME);
465+
if (peek_event && cthread_peek) peek_event->notify(PEEK_TIME);
416466

417467
#ifdef SCT_TLM_DEBUG
418-
if (getTime == sc_time_stamp()) {
468+
if (cthread_get && getTime == sc_time_stamp()) {
419469
cout << sc_time_stamp() << " " << name() << ", ERROR: multiple get\n" << endl;
420470
sc_assert (false);
421471
}
@@ -492,6 +542,12 @@ class sct_prim_fifo :
492542
sync_ready = syncReady;
493543
}
494544

545+
/// Set the FIFO used for Target/Initiator simulation
546+
void setTargInit(bool sync = false) {
547+
if (sync) targ_init_sync = true;
548+
else targ_init = true;
549+
}
550+
495551
public:
496552
template <typename RSTN_t>
497553
void clk_nrst(sc_in_clk& clk_in_, RSTN_t& nrst_in) {
@@ -554,9 +610,22 @@ class sct_prim_fifo :
554610

555611
void addPeekTo(sc_sensitive& s) override {
556612
auto procKind = sc_get_current_process_handle().proc_kind();
613+
bool cthread = procKind == SC_THREAD_PROC_ || procKind == SC_CTHREAD_PROC_;
614+
615+
if (peek_event) {
616+
if (cthread_peek != cthread) {
617+
cout << "\nDouble addPeekTo() with different process kinds for : "
618+
<< name() << endl;
619+
assert (false);
620+
}
621+
} else {
622+
auto eventName = std::string(std::string(basename()))+"_peek_event";
623+
peek_event = new sc_event( eventName.c_str() );
624+
cthread_peek = cthread;
625+
}
557626

558627
if (procKind != SC_CTHREAD_PROC_) {
559-
s << get_event;
628+
s << *peek_event;
560629
}
561630
}
562631

components/common/sctcommon/sct_property.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -360,10 +360,10 @@ class sct_property_storage {
360360
opt.spawn_method();
361361
opt.dont_initialize();
362362
opt.set_sensitivity(event);
363-
std::string procname = inThread ?
364-
sc_get_current_process_handle().basename() :
365-
(std::string("AssertionAtLine") +
366-
propstr.substr(propstr.find_last_of(':')));
363+
std::string procname = (inThread ?
364+
std::string(sc_get_current_process_handle().basename()) :
365+
std::string("AssertionAtLine")) +
366+
propstr.substr(propstr.find_last_of(':'));
367367
sc_spawn(*propInst, procname.c_str(), &opt);
368368

369369
stor.emplace(hash, propInst);

components/common/sctcommon/sct_signal.h

-7
Original file line numberDiff line numberDiff line change
@@ -159,13 +159,6 @@ class sct_signal<T, 1> :
159159
if (procKind != SC_CTHREAD_PROC_) {
160160
s << thrd_event;
161161
}
162-
// It needs to be updated in @end_of_elaboration() as port is
163-
// not bound here, see #34
164-
//if (clk_in && clk_in->get_interface() != sct_curr_clock->get_interface()) {
165-
// std::cout << "Signal " << name() << " added to process sensitivity"
166-
// << " lists which have different clock inputs\n";
167-
// assert(false);
168-
//}
169162
clk_in = sct_curr_clock;
170163
thrdEvent = true;
171164
} else {

0 commit comments

Comments
 (0)