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. 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? In the context of the DPI, is a function call with a fork/join_none thread "pure" or "context". I have never been opposed to this enhancement. I just have not seen a clear proposal for what is actually needed to implement it. Dave > -----Original Message----- > From: 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 Sun Feb 26 09:59:07 2006
This archive was generated by hypermail 2.1.8 : Sun Feb 26 2006 - 09:59:46 PST