All,
This is the last of the open issues. Hooray!
I include the email trail below.
John A
Clause 5.2.1.2 Evaluation phase, paragraph 4 is about immediate
notification, yet you state "The currently executing process instance may
itself be one such process, in which case it will be executed more than
once in the same evaluation phase." I think the statement is incorrect or
out of context.
If an application executes sc_event::notify(void), then it is not waiting
and cannot be resumed by an immediate notifiication. On the other hand I
can see how a process can execute a wait in a delta cycle and get resumed
by another process via immediate notification in the same delta cycle.
Perhaps some clarification is still needed.
David
----------------------------------------------------------------------------------------
David,
This is a tricky issue, which I guess is why I missed it first time
around. I believe the LRM is now correct. Here is an example that
illustrates the point:
struct Top: sc_module
{
SC_CTOR(Top)
{
SC_THREAD(T);
sensitive << ev;
}
sc_event ev;
void T()
{
for(;;)
{
cout << "T delta count " << sc_delta_count() << endl;
ev.notify();
wait();
}
}
};
The immediate notification causes the process to be triggered repeatedly
within a single evaluation phase. The same holds for method and thread
processes. The process is statically sensitive to ev and there is no
dynamic sensitivity in place. . See NOTE 4 below 5.2.1.2.
If you want to raise this as an issue on the reflector, that's fine by me.
Right now I am just collating issues as they are raised and deferring the
discussions until Jan/Feb.
Cheers,
John A
----------------------------------------------------------------------------------------
John pointed out to look at Note 4 in that same section, and gave me some
coding supporting the description.
I then tried a variant, which I provide herein. Assume the following
convenience macro:
#define DISPLAY_INFO\
do {\
repetition = (lastfile == __FILE__ and lastline == __LINE__)?
repetition+1 : 0;\
cout << "Count: " << count
<< " File: " << __FILE__\
<< " Line: " << __LINE__\
<< " Func: " << __func__\
<< " Time: " << sc_time_stamp()\
<< " Delta_count: " << sc_delta_count();\
if (repetition != 0) cout << " (repeated " << repetition << " time)";\
cout << endl;\
lastfile = __FILE__; lastline = __LINE__;\
} while(false)
Assume the preceding variables are globally declared elsewhere for
convenience.
int count(0);
string lastfile("");
int lastline(0);
Consider the following:
struct Ex2: sc_module
{
SC_CTOR(Ex2)
{
SC_THREAD(ex2_thread2);
sensitive << event;
SC_THREAD(ex2_thread1);
sensitive << event;
}
sc_event event;
void ex2_thread1(void)
{
cout << "Start -------" << endl;
for (int i=0;i!=7;++i) //< limit runaway delta cycles
{
DISPLAY_INFO;
event.notify(); //< immediate notification
wait(); //< dynamically specify static sensitivity
++count;
}
}
void ex2_thread2(void)
{
cout << "Start -------" << endl;
for (int i=0;i!=7;++i) //< limit runaway delta cycles
{
DISPLAY_INFO;
wait(); //< dynamically specify static sensitivity
}
}
};
Here is the result (notice that thread1 executes twice from an immediate
notification, but thread2 does not):
SystemC 2.3.0_20100801_beta-OSCI --- Nov 23 2010 07:04:48
Copyright (c) 1996-2006 by all Contributors
ALL RIGHTS RESERVED
Start -------
Count: 0 File: ex2.cpp Line: 43 Func: ex2_thread2 Time: 0 s Delta_count: 0
Start -------
Count: 0 File: ex2.cpp Line: 22 Func: ex2_thread1 Time: 0 s Delta_count: 0
Count: 1 File: ex2.cpp Line: 22 Func: ex2_thread1 Time: 0 s Delta_count: 0
(repeated 1 time)
Count: 1 File: ex2.cpp Line: 43 Func: ex2_thread2 Time: 0 s Delta_count: 0
Count: 2 File: ex2.cpp Line: 22 Func: ex2_thread1 Time: 0 s Delta_count: 0
Count: 3 File: ex2.cpp Line: 22 Func: ex2_thread1 Time: 0 s Delta_count: 0
(repeated 1 time)
Count: 3 File: ex2.cpp Line: 43 Func: ex2_thread2 Time: 0 s Delta_count: 0
Count: 4 File: ex2.cpp Line: 22 Func: ex2_thread1 Time: 0 s Delta_count: 0
Count: 5 File: ex2.cpp Line: 22 Func: ex2_thread1 Time: 0 s Delta_count: 0
(repeated 1 time)
Count: 5 File: ex2.cpp Line: 43 Func: ex2_thread2 Time: 0 s Delta_count: 0
Count: 6 File: ex2.cpp Line: 22 Func: ex2_thread1 Time: 0 s Delta_count: 0
...
I see this is specified in the standard, but I contend it is very
confusing and non-intuitive. Interestingly, if you reverse the process
registrations, the repetition goes away. I imagine this could lead to some
very hard to debug problems. Of course I routinely advise students to be
careful with immediate notifications, but perhaps caution is not enough...
My expectation was that sc_event::notify(void) would only affect those
processes that are already have executed some form of wait() (or returned
in the case of SC_METHOD). My internalized understanding of "static
sensitivity" is that it is a sensitivity list created during elaboration
and unable to change after that. The sc_event::wait(void) method is simply
an SC_THREAD's way of dynamically waiting on the statically specified
list.
Admittedly, it is problematic coding to have a process wait an event like
this.
Should the above behavior be allowed?
Why does it happen (what is the mechanism)?
Perhaps more importantly:
Is this behavior expected?
Is there a good application of this behavior?
Is this unavoidable?
David B
-- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.Received on Tue Jan 11 05:59:30 2011
This archive was generated by hypermail 2.1.8 : Tue Jan 11 2011 - 05:59:31 PST