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

From: Rich, Dave <Dave_Rich_at_.....>
Date: Sun Feb 19 2006 - 06:51:13 PST
Hi Arturo,
 
There are a few problems with the two versions of F(). The second version of F() has the trigger -> statement, which is not allowed in a function. And the first version of F() has task calls T1 and T2 (Cliff - this is what you missed, the "T" is for "Task") inside the function call.
 
Vera may not have made much of a distinction between tasks and functions, but it's pretty fundamental in Verilog and SystemVerilog. Many other features of the language depend on it. For example, I'm sure the DPI does not expect threads to be created from exported function calls. And as I mentioned before, packages should not have spontaneously generated threads.
 
If the real issue is starting a thread with a constructor, then I could see doing something for that case only. The constructor is already a very special function call; and we need to make sure the constructor is only called from a place where it would be legal to start a thread anyways. Then we're not opening up the door by allowing general functions to call tasks and create threads.
 
Dave
 

________________________________

From: owner-sv-ec@eda.org on behalf of Arturo Salz
Sent: Fri 2/17/2006 4:52 PM
To: sv-ec@eda.org; sv-bc@eda.org
Subject: RE: [sv-ec] RE: [sv-bc] Can a function contain a fork/join/any/none?



As Dave has learned, forking off background threads in class constructors

is a very common usage in the world of transaction modeling. A transactor

will typically create one or more threads for each instance created during the

simulation. The primary motivation of model writers is to encapsulate all the

inner workings inside the model and not expose the modeling details to users 

of the model.

 

When 1364-2001 writes "A function shall execute in one simulation time unit", I

understand that users take that quite literally as the meaning of "time consuming".

And, after introducing fork/join_none, which is definitely not time consuming, I

can understand why many people would conclude that fork/join_none must be 

allowed in functions. Frankly, I see nothing wrong with allowing fork/join_none in

functions. A fork/join_none is semantically equivalent to triggering the execution

of one or more threads from within the function, as in the following code:

 

            function void F();                       function void F();

                // some initialization                   // some initialization

                fork                                          -> ev;

                    T1();                                  endfunction

                    T2();

                join_none                              always @ev T1();

            endfunction                               always @ev T2();

 

Both versions of the above function F() accomplish the same thing, except that 

the one on the right is more verbose and doesn't encapsulate the functionality

as well as the one the left. If the threads triggered by the function are related

to the function call --- for example, they may be associated with the particular 

transactor being created --- then the code on the right becomes a exceedingly more 

difficult to write: For example, the function may have to add the transactor handle 

to some dynamic data such as queue, which is then examined by the threads.

It's also important to remember that the code on the right  cannot be written in a 

package, thus, making life even more difficult for both model writers and users of 

the model.

 

Forking threads from within a constructor is very common idiom in both Vera and 

C++ models. If we were to disallow this in P1800, I imagine a lot of IP writers will 

be upset. I suspect that these are the same people that have been questioning 

Dave on the availability of this feature. I'm not advocating that SystemVerilog allow

all types of fork/join within functions, only fork/join_none, which is fundamentally

not a time consuming construct.

 

Sorry for blasting this to both sv-bc and sv-ec, but I believe it is important to let

both committees know about this (sorry for the copies Cliff).

 

            Arturo

 

 -----Original Message-----
From: owner-sv-ec@eda.org [mailto:owner-sv-ec@eda.org] On Behalf Of Rich, Dave
Sent: Friday, February 17, 2006 1:31 PM
To: sv-ec@eda.org
Subject: [sv-ec] RE: [sv-bc] Can a function contain a fork/join/any/none?

 

I'm just going to copy the sv-ec from now on, since from the perspective

of the sv-bc, this only deal with issues related to the testbench. The

main place that I have seen this is in the new function for a

constructor.

 

This snippet of code below was submitted to the SPIRIT working group

back in September. Since then I have seen it in a few other places,

basically the same.

 

class ahbram;

   ahb_slv_if.comp sigs;

   local ahbram_callbacks cbs[$];

   local bit [1023:0] ram;

 

   extern function new(string          instance,

                       ahb_slv_if.comp sigs);

 

   extern function bit [1023:0] peek(bit [31:0] addr);

   extern function void poke(bit [  31:0] addr,

                             bit [1023:0] data);

 

   extern function void register_callbacks(ahbram_callbacks cb);

 

   extern local task main();

endclass: ahbram

 

 

function ahbram::new(string          instance,

                     ahb_slv_if.comp sigs);

   this.sigs = sigs;

   fork

      this.main();

   join_none    

endfunction: new

 

 

I would grant that if a fork/jone_none were legal in a function, then I

can see stretching the LRM to say that the task call inside the fork is

executing outside the function, or even stretching the LRM to say that

the "new" function is not really a function, its a constructor and

doesn't have to follow the rules of Verilog function.

 

Now we have the statement

 

ahbram R1 = new();

 

creating a thread. But that statement could be in a package, or inside

another function be called outside of a procedural context

 

Dave

 

 

 

> -----Original Message-----

> From: owner-sv-bc@eda.org [mailto:owner-sv-bc@eda.org] On Behalf Of

Brad

> Pierce

> Sent: Friday, February 17, 2006 12:23 PM

> To: sv-bc@eda.org

> Cc: sv-ec@eda.org

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

> 

> Cliff,

> 

> That's not at all what I asked.  I don't see anything wrong with using

> fork-join in functions.

> 

> INSTEAD, I asked Dave, who started this thread, why so many people are

> asking him the question in his subject line.  My guess is that they

are

> indeed seeing examples of this style and then asking Dave, "is that

> really legal?".

> 

> Yes, it's really legal.

> 

> How might they be seeing examples of this legal usage?  Maybe the

people

> that are asking him are tool developers who are getting bug reports

> about this legal usage, in which case the need for backward

> compatibility would be even stronger.  It would be interesting to

know.

> 

> -- Brad

> 

> -----Original Message-----

> From: owner-sv-bc@eda.org [mailto:owner-sv-bc@eda.org] On Behalf Of

> Clifford E. Cummings

> Sent: Friday, February 17, 2006 12:01 PM

> To: sv-bc@eda.org

> Subject: [sv-bc] Can a function contain a fork/join/any/none?

> 

> Hi, All -

> 

> Just the sv-bc on this message (I'm tired of getting two of everyone

> of these messages)

> 

> Brad asked the question and I think Stu hinted around the question:

> 

> What is the use-model for adding fork-join to a function?

> 

> Are there any engineers doing this? (And has anybody slapped them for

> doing it?  :-) )

> 

> The engineers that ask this question, do they understand that no

> delays are allowed in a function (not even #0 delays or nonblocking

> assignments that cause events to be scheduled in later event regions

> within the same timestep) and that fork-join are generally not

> synthesizable and are really most useful when you add some form of

> delay to the forked paths within a testbench?

> 

> I can't say for sure, but I don't believe either Stu or I have ever

> shown engineers a fork-join in a function in training and I don't

> think we ever intend to teach this coding style.

> 

> I understand that it might be important to add some form of

> clarification to the LRM but whatever clarification we add should

> come with the strong editorial comment that this is/was a bad idea.

> 

> I will support whatever the group goes for on this and then I will

> never teach an engineer to add fork-join to a function (unless

> somebody can come up with some ultra-astonishing use-model that I

> have not heretofore recognized).

> 

> Regards - Cliff

> 

> ----------------------------------------------------

> Cliff Cummings - Sunburst Design, Inc.

> 14314 SW Allen Blvd., PMB 501, Beaverton, OR 97005

> Phone: 503-641-8446 / FAX: 503-641-8486

> cliffc@sunburst-design.com / www.sunburst-design.com

> Expert Verilog, SystemVerilog, Synthesis and Verification Training

> 

 

 
Received on Sun Feb 19 11:30:24 2006

This archive was generated by hypermail 2.1.8 : Sun Feb 19 2006 - 11:32:02 PST