Re: [sv-ec] RE: [sv-bc] RE: Can a function contain a fork/join/any/none?

From: Steven Sharp <sharp_at_.....>
Date: Thu Mar 23 2006 - 17:30:57 PST
>From: Gordon Vreugdenhil <gordonv@model.com>

>The rules for these forms are yet to be defined.

Not sure what you are trying to say.  The LRM has clear rules about
forks, and makes no exceptions for when they are in functions.

From 11.6:

"A Verilog fork...join block always causes the process executing the
fork statement to block until the termination of all forked processes."

From Table 11-1:

"join: The parent process blocks until all the processes spawned by this
       fork complete.
 join_any: The parent process blocks until any one of the processes spawned
           by this fork completes."
           
You might be contemplating the addition of new yet-to-be-defined rules for
inside functions, but right now they are defined as the process blocking.


>I don't have any problem with thread *dispatch* within a
>function; I do have a problem with having functions suspend
>the thread that enabled the function.

Which the LRM clearly says that fork...join/join_any do.  You could
change the LRM to re-define the behavior of fork...join inside a function,
so that this was not true.  But if you are going to explicitly define
them to be equivalent to a begin...end, then what is the point of
allowing these constructs in functions in the first place?


>The implication is that I would be in favor of any
>construct inside a fork..join_none and would also accept
>fork..join  blocks which respect function restrictions (meaning
>they would be equivalent to a series of sequential blocks and
>don't really need to be described as suspending).

But they are currently described as suspending.  Furthermore, they
are not even quite equivalent to sequential blocks.  They have a
different effect on hierarchical seeding of randomization than a
sequential block has.  So you could add a special rule that says
that fork...join inside a function behaves the same way as a
begin...end, or a begin...end with the statements executed in a
nondeterministic order, or something similar.  But there would
still be a subtle difference from the current definition.

As I have said before, just focusing on whether a fork...join/join_none
could block the parent process is inadequate when considering whether
they should be allowed in functions.  They have other semantics in
SystemVerilog that must be considered, such as hierarchical seeding,
disable fork, wait fork, fine-grain process control, and interaction
with Verilog disables.


>I would have problems with a fork..join_any since either
>the blocks respect the function restrictions (meaning that the
>construct is essentially useless since a simulator could then just
>pick one of the "threads" arbitrarily and never actually suspend)

It has to execute all the threads eventually, so it might as well
execute them all sequentially before continuing with the parent,
just like a fork...join.

The only reason to execute just a single thread is if the rule were
that at least one thread must respect the function restrictions, to
ensure that the function does not actually suspend, but the others
were allowed to block.  I am not suggesting this as an actual rule,
just following your logical train of thought.  Note that this could
always be rewritten by pulling the non-blocking thread (which would
have to be statically determinable) out of the join_any and then
turning it into a join_none.

Any rule which preserves your version of the non-blocking rule for
functions will make both join and join_any pointless inside functions.


>My working rule here is that if the function must "wait"
>for a thread then the thread must be expressable as
>a valid sequential block within the function.  This approach
>seems to me to be a reasonable compromise between allowing
>functions such as "new" to create threads while not
>opening the door for real thread suspensions within
>functions.

As noted earlier, technically the thread is never expressable as a
sequential block, since expressing it that way would change the
hierarchical seeding, which would affect any randomization calls
in the thread or its parent.  I don't think you want your rule to
depend on the presence or absence of randomization calls in the
design.  It is a minor issue, but technically a valid one.


Steven Sharp
sharp@cadence.com
Received on Thu, 23 Mar 2006 20:30:57 -0500 (EST)

This archive was generated by hypermail 2.1.8 : Thu Mar 23 2006 - 17:31:15 PST