Dave, We should allow statements contained in a fork/join_none inside a function have the same rules as for statements contained in a task. Therefore, all timing controls and calls to tasks are allowed in these fork/join_none blocks. Otherwise, the fork/join_none would not be able to do the background activity it needs to do. I believe where we essentially differ on this issue is whether object constructors should be functions or tasks. A call to an object constructor: object = new(x, y, z); looks and acts like a function call in that it returns the newly created handle. If the constructor was a task then the syntax would be clumsy, and any arbitrary blocking statement would be allowed during the construction. Constructors not returning in a single evaluation step are very problematic because they lead to partially constructed objects, which violate basic object-oriented principles. Making the constructor a function, allowing functions to spawn off background activity with a fork/join_none, and making sure that the constructor returns in a single evaluation step, seem to me to make everything fit nicely. Other comments embedded below in your email. Phil -----Original Message----- From: Rich, Dave [mailto:Dave_Rich@mentor.com <mailto:Dave_Rich@mentor.com> ] Sent: Sunday, February 26, 2006 12:59 PM To: Phil Moorby; sv-ec@eda.org Cc: Mehdi Mohtashemi Subject: RE: [sv-ec] RE: [sv-bc] Can a function contain a fork/join/any/none? Hi Phil, I don't think most people are questioning the usefulness of allowing a constructor to create a thread. It's all the additional questions that this proposed syntactical mechanism opens up. I don't think your argument about the PLI holds up because there are lots of things you can do via the PLI that you can't do via the language. Maybe we need to consider all those things the PLI can do, that can't be done in SV ;-) OK. So it's legal to have a fork/join_none in a functional call. But it's clearly illegal to call a task from a function. Are you proposing to ignore all rules about functions when the statements are within a fork/join_none, or just some of them? Then there are the rules about function calls in other parts of the language, like calls from assertions and constraints. Is the fork statement a side effect, or is the task call a side effect? I would consider a fork/join_none inside a function as a useful and necessary side effect. A task call would only be allowed inside the fork/join_none, and therefore part of the fork/join_none side effect. Calls from assertions and constraints might present some usual non-determinism, but just as in function calls from the RHS of cont-assigns, or in variable gate delay expressions, etc., there are no new problems here. In the context of the DPI, is a function call with a fork/join_none thread "pure" or "context". Not sure what you mean by this. I have never been opposed to this enhancement. I just have not seen a clear proposal for what is actually needed to implement it. I would hope that we are working towards a clear proposal. Dave > -----Original Message----- > From: owner-sv-ec@eda.org [mailto:owner-sv-ec@eda.org <mailto:owner-sv-ec@eda.org> ] On Behalf Of Phil > Moorby > Sent: Sunday, February 26, 2006 9:06 AM > To: sv-ec@eda.org > Cc: Mehdi Mohtashemi > Subject: RE: [sv-ec] RE: [sv-bc] Can a function contain a > fork/join/any/none? > > Functions in Verilog were designed to be different from tasks for one > very good reason: it was necessary for the evaluation of expressions to > complete and have their value returned within a single evaluation step. > In other words, the simulator must not context switch to other events > until it finishes evaluating the expression and obtains the result. > Functions and function calls must therefore be restricted and not allow > their returning thread to block. With this restriction, blocking can > only occur at a statement level, never at an expression operand level. > This restriction reduces potential non-deterministic situations, and > enables the simulator to optimize its runtime code. > > Functions have always allowed side effects (both good and bad). My > definition of side effects includes the ability to modify variables > outside the function boundary and calling system and PLI tasks and > functions. Side effects have the potential of effectively spawning off > additional threads of activity, such as @ triggers on the outside of the > function boundary or PLI event creations, but this does not affect the > requirement of evaluating the function in a single evaluation step. > Although some side effects are considered to be bad, and certainly a > source of non-determinism, some side effects are actually quite useful. > For instance, PLI calls from functions can setup background activity, > and this is considered a very useful (and deterministic) feature by some > users. This train left the station 21 years ago! > > Lets not get confused with the use of functions in code for synthesis; > we are talking here of code used to simulate the environment or verify > the design. > > Now to SystemVerilog and object creation. Like the evaluation of > expressions, it is highly desirable that the creation of an object be > performed in a single step without blocking. Object creation involves > some behind-the-scene work by the system (to manage memory for instance) > in addition to calling and completing the object constructors. It is > highly desirable that only the object constructor code have access (read > or write) to an object under construction, that is, a partially > initialized object. Otherwise, it may lead to many situations of > non-determinism that the user did not intend, and that are very hard to > debug. > > For these reasons it only makes sense to make the constructor a function > not a task. > > Another highly desirable feature of objects is to be able to setup some > background activity that does its work throughout simulation. The > constructor code is the perfect place to set off this background > activity, especially when true object-oriented principles are followed. > The usual side effect workaround is ugly, overtly complex, and error > prone, and the fork/join_none is a much better programming feature to > spawn this activity. > > This leads to only one logical conclusion: the constructor must be a > function, and it must allow fork/join_none statements. > > Also, because the constructor function must to be able to call other > functions (simply for good programming practice), it only makes sense to > allow fork/join_none in any and all functions. > > In general, when considering these language features, I believe we > should follow two guiding principles: > 1) The feature is significantly useful for users > 2) The simulator can implement the feature without confusing the user > > Another SystemVerilog guiding principle is to avoid forcing users to > code needed functionality using PLI calls, and instead enable the same > functionality to be written directly in the language. > > The ability to have fork/join_none statements in functions satisfies > these principles. > > PhilReceived on Mon Feb 27 15:13:28 2006
This archive was generated by hypermail 2.1.8 : Mon Feb 27 2006 - 15:14:00 PST