Re: [sv-ec] Comments on event changes CH17.html


Subject: Re: [sv-ec] Comments on event changes CH17.html
From: Arturo Salz (Arturo.Salz@synopsys.com)
Date: Thu Jan 09 2003 - 13:59:59 PST


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 - 14:01:39 PST