Subject: Re: [sv-ec] Comments on event changes CH17.html
From: Arturo Salz (Arturo.Salz@synopsys.com)
Date: Thu Jan 09 2003 - 18:00:38 PST
Messagejay,
I agree with both your points:
1) Timing controls would alter the scheduling order.
2) I'm opposed to any reliance on execution of sub-processes.
However, I do believe that the creation of fork..join subprocesses should be documented.
This is the sort of thing that vendors spend a lot time doing black box testing in order to
match each others semantics, so it might as well be documented. That will only ensure
a higher degree of inter-tool determinism, which is different from encouraging users to rely
on the schedule ordering. For that purpose users should use any of the synchronization
mechanisms available.
Arturo
----- Original Message -----
From: Jay Lawrence
To: Arturo Salz ; sv-ec@eda.org
Sent: Thursday, January 09, 2003 5:52 PM
Subject: RE: [sv-ec] Comments on event changes CH17.html
Just reread your reply ... On the concept of source order of fork/join, yes in this trivival example everyone would get same answer, but if the sub-processes created contained any sort of delay or event controls, all bets are off on the order in which embedded events would be seen.
I would be opposed to any reliance on "source order" execution of fork/join sub-processes.
Jay
-----Original Message-----
From: Arturo Salz [mailto:Arturo.Salz@synopsys.com]
Sent: Thursday, January 09, 2003 5:00 PM
To: Jay Lawrence; sv-ec@eda.org
Subject: Re: [sv-ec] Comments on event changes CH17.html
Jay,
You are correct to state that the LRM needs to specify the point in
the Verilog simulation cycle in which persistent events change back
to the "off" state. However, I do not believe that we need to add yet
another item to the stratified event queue. It's perfectly OK to reset
events during read-only-synchronize (at the same time as monitor
events). This is because only the positive edge (off -> on transition)
is visible outside the simulation kernel. A process can't be sensitive
to the "off" transition so the reset is akin to the monitor list update.
I assumed that this was implied from the language "until simulation
time advances", but it would be good to state it explicitly.
I appreciate what you are trying to do with the "non-blocking event trigger".
Your proposal is in fact similar to the original Vera functionality in which
the "persistency" of an event was a function of the trigger function. That
functionality was changed to facilitate event management in Verilog by
making the persistency an explicit part of the event.
Unfortunately, your proposal doesn't solve the problem, it merely reduces
the likelihood of its occurrence when the expects (@) execute at the same
time as blocking assignments. This precludes deterministic operation of
processes that are both sensitive to as well as trigger events, since that
might lead to multiple NBA times. Your message acknowledges this fact,
and states that it very rarely is a problem. But, events are used primarily
for verification, and verification code executes during the "verification phase",
which takes place after all non-blocking assignments, thus, your proposal
might simply exacerbate the existing non-determinism problem by adding
the scheduling or processing order of non-blocking events to the equation.
The bottom line is that if the triggered state of an event does not persist
throughout the time step, the problem reappears.
For example, consider the following example:
event E1, E2;
fork
T1: begin @ E1 ; @ E2; end
T2: ->> E2;
T3: ->> E1;
join
Depending on the scheduling order of event triggering, the first process, T1,
will either unblock or block forever. If this is rewritten with persistent events
then regardless of the scheduling order, T1 always unblocks. Many other
simple examples will work deterministically with persistent events but will
exhibit scheduling order dependencies using non-blocking event triggers.
Finally, I'd like to clarify something about your example. The example does
capture the gist of the problem (the lack of determinism due to scheduling
order) that motivates persistent events, and it is strictly correct since the V2K
LRM does not explicitly specify the execution order of processes within a
fork..join. However, all Verilog implementations of which I'm aware do execute
the processes in source-order (T1, T2, T3 in the example). As a result, the
outcome will always be to display "T1". I simply wanted to clarify this in case
someone tries the example and deems this not to be a problem due to the
inherent determinism of existing implementations. I added a paragraph to
this effect in the 3.1 LRM (see section 9.7) since I believe that specifying the
order provides for better cross-tool determinism (and this is the de-facto way
in which all vendors implement fork..join).
Arturo
----- Original Message -----
From: "Jay Lawrence" <lawrence@cadence.com>
To: <sv-ec@eda.org>
Sent: Monday, January 06, 2003 3:47 AM
Subject: [sv-ec] Comments on event changes CH17.html
I assume we are going to begin today where we left off on the event
debate. I believe the debate now focuses more around the contents of
http://www.eda.org/sv-ec/CH17.html than what is in the Draft 1 LRM so my
comments refer to that document.
Syntax nits
----------
- It currently says:
> The syntax to declare a non-persistent event is:
> event event_dentifier;
I believe this should be 'event_identifier' this occurs a bunch of times
in the changes document.
- last example is:
> fork
> T1: while(1) @ E2;
> T2: while(1) @ E1;
> T3: begin
> E2 = E1;
> while(1) -> E2);
> end
>join
The line "while(1) -> E2);" has a syntax error, the last ')' is not
needed.
This would also send NC into an infinite loop forever triggering E2. It
think the entire line should just be '-> E2;' and remove the while
altogether (maybe it needs a begin/end).
Persistent Event Clarification Needed
-------------------------------------
If we are going to accept this concept of an event that "persists
throughout the time-step, that is, until simulation time advances". We
are going to need to propose a change in the simulation cycle (1364 -
Chapter 5) to add a portion of the stratified event queue where these
things change state back to "off" after the monitor events have
executed.
Alternative Proposal for "Persistent Event" - "Non-blocking Event
Trigger"
------------------------------------------------------------------------
--
Note: this is different than what Adam K. previously proposed (and was
rejected)in IEEE 1364, that was events with transport delays, but had
the same title.
The big value added by the persistent event is the reduced
non-determinism created by allowing the event to remain triggered in
order to avoid race conditions which occur from 0-delay simulation
semantics. This is exactly like the race-conditions that are created by
using blocking assignments.
I propose the we introduce a new operator ->> which we will call the
non-blocking trigger operator. The operator takes a single event as an
argument:
event E;
->> E;
The effect of this operator is that the event E will be triggered in the
non-blocking assignment phase of the simulation cycle. In 1364, this
would be defined as adding a "non-blocking assign update event" to the
current simulation time. The effect of this update event would be to
trigger the referenced event.
The procedural code context in which the non-blocking trigger occurs
continues to execute sequentially (does not block). This is also true of
the regular trigger '->' operator, so the name non-blocking event
trigger refers to when the event is scheduled rather than what happens
in the sequential context.
This delaying of the event trigger until NBA-time disambiguates the
triggering of events in exactly the same way that non-blocking
assignments disambiguated assignment many years ago, and requires no
changes to the simulation cycle.
It also has the advantage that events do not have to take on the
characteristic of having a persistent value over time. They are still
just instantaneously triggered (like the (posedge clk) in the CH17
proposal), so a new declaration for events (event bit) is not necessary.
All events could be triggered in this way. Note, I actually like the
promotion of events to first class objects that can be assigned to one
another and passed to tasks. I would even allow them to occur in
'struct' and 'union' objects to embed an event with data.
The following example is ambiguous.
event E1;
fork
T1: begin @ E1 $display("T1"); end;
T2: -> E1
T3: begin @ E1 $display("T3"); end;
join
Depending on the simulator (or even simulation cycle) Either T1 or T3,
or both will display and the fork/join may or may not ever unblock. If
you replace the trigger with a non-blocking trigger.
event E1;
fork
T1: begin @ E1 $display("T1"); end;
T2: ->> E1
T3: begin @ E1 $display("T3"); end;
join
The order of execution becomes unimportant. T1 and T3 would both block
and the trigger would be scheduled for NBA-time. When NBA-time arrives,
both processes would always see the event.
There of course remain multiple NBA times possible in a given simulation
cycle, but that very, very rarely causes issues with blocking vs.
non-blocking assignment ambiguity. This solves the race condition
problem triggering events with no more and no less ambiguity than
non-block assignments did without introducing a new class of object or
changing the simulation cycle.
Note, a logical extension of this proposal would also be to allow a
delay control after the operator:
->> #5 E1;
I bring it up here just because someone will. I think it makes sense but
wouldn't protest too hard if only the immediate case was allowed. This
is closer to Adam's proposal on adding transport delays to event
triggering.
Jay
This archive was generated by hypermail 2b28 : Thu Jan 09 2003 - 18:00:08 PST