Hi, All - I find myself in disagreement with Gord on a few of these, so I guess we do need people to voice opinions. See below. At 01:19 PM 8/26/2005, Gordon Vreugdenhil wrote: >Let me take a crack at the name resolution scenarios >that Mark raised and add a few more really bad cases. > >Since forward references to subprograms (tasks/functions) are >historically legal, they must be treated a bit differently. > >Here is a semi-operational description of what I think the >combination of the P1800 LRM rules and historical behavior requires: > 1) a task/function reference cannot be resolved upwards > from a scope until the scope (and possibly parents) are > complete. > 2) a tack/function reference does inspect imports in an > eager manner but doesn't look upwards until (1) is > satisfied. I can't find the definition of "eager" ;-) But I think I disagree. I don't think package::* functions and tasks are "eagerly" imported. Maybe this is a tool problem that may have to change the way we think about it, but I am of the opinion that local function and task calls do not cause immediate package::* importation. I believe the module or $unit is read to see if functions and tasks have been defined and if they have not been defined, the tool then imports the tasks and functions; otherwise, we get very different results by putting local module task and function declarations at the beginning of a file from putting them at the end of a file. Very un-Verilog-like behavior. This impacts some of the examples below. > 3) all other non-type resolution that escapes to $unit must > also be deferred but is done in an "eager" manner in the > intervening scopes. > 4) any identifier is located upwards, including $unit seen > "so far" and its imports and resolution occurs immediately > if the identifier can be resolved to a type. > 5) a "potentially visible name" becomes directly visible as > early as possible but "upwards" potential visibility > can be deferred by earlier rules. > > >Not the most obvious set of rules, but I think that this >is pretty close. > >Here are the implications of this for each of the designs: > > >1) > >function int fn(); > return 0; >endfunction > >module m(); >int x; >initial x = fn(); // which fn() does this bind to? > >function int fn() > return 1; >endfunction > >endmodule > > >In "x = fn()", fn means m.fn by rule 1. I agree. >2) > >package p; >function int fn(); > return 0; >endfunction >endpackage > >module m(); >import p::*; >int x; >initial x = fn(); // which fn() does this bind to? > >function int fn() > return 1; >endfunction >endmodule > > >By rule 2, fn() binds to p::fn, making it directly visible >in m. This causes the declaration of m.fn to produce an error. I disagree. I don't think we even start looking inside of package::* until we know if the function or task has been declared locally. I believe the function called should be m.fn. >3) > >package p; >function int fn(); > return 0; >endfunction >endpackage > >import p::*; > >module m(); >int x; >initial x = fn(); // which fn() does this bind to? > >function int fn() > return 1; >endfunction >endmodule > > >By rule 2, fn() binds to m.fn since you don't inspect >the parent's import until the module scope is closed. > >This also implies that "fn" is not imported into >$unit and thus declaring a new "fn" inside $unit >would be legal. I agree. >4) > >package p; >function int fn(); > return 0; >endfunction >endpackage > >import p::*; > >module m(); >int x; >initial x = fn(); // which fn() does this bind to? >endmodule > >function int fn() > return 1; >endfunction > > >This is an error. By rule 1 & 2, upon completing the module >scope, "fn" is found via the import. $unit::fn then conflicts >with the visible p::fn. I disagree. I believe $unit.fn is used and the $unit.package::* version is never imported. Again, it is very un-Verilog-like to get different results based on where a function or task is declared within a file. >5) > module m; > parameter p = 1; > function int fn(); > return 0; > endfunction > if (p) begin:b // generate > reg x = fn(); > function int fn(); > return 1; > endfunction > end > endmodule > > >fn() binds to m.b.fn() since it is not resolved until the >close of the generate scope. I agree. >6) > // file mode compilation unit > module m; > int x = fn(); > endmodule > function int fn(); > return 1; > endfunction > > >No error. The foward reference is resolved in $unit >when $unit is closed. I agree. >7) > // file mode compilation unit > module m; > int x = a; // error? > endmodule > localparam a = 1; > > >No error. "a" is not resolved until $unit is closed. I disagree. I believe this is an error, but only because variables, wires, parameters, etc. declarations have always been required before use. I believe this is the way current compilers are treating this. >8) > > typedef int T; > module m; > T x; > typedef real T; > T y; > endmodule > > >This one is nasty. By rule 4, the $unit version of T >is visible in "m" during the declaration of x. But >since this isn't an import, there is no expectation that >"T" can't be redefined in m. This implies that this >design is legal with x being an int and y being a real. Nasty indeed! But I believe this is an error. I don't think you should be able to change the definition of a type after it has been used with an existing definition. Of course, put the T x; declaration after the typedef real T; declaration and only the local typedef is used and is legal. >9) > module foo; > reg x; > > initial begin:b > automatic reg y = x; > automatic reg x; > end > endmodule > > >Similar case to (8) but follows rule (3). I am not as sure about this one but I still believe this is illegal. Redefinition of x after it was first legally used in another form. >I am not at all happy by my read of things in terms of >the rule set that I outlined above. > >For types we *must* have early resolution due to parse >issues. And for historical reasons, we really need to >preserve the subprogram resolution behavior. > >So, why not require that all non-subprogram resolution >be done in the same manner as types *with* the additional >requirement that any non-imported escaping reference >becomes a "reserved" identifier in the referring scope >so that no local redefinition of the name is permitted. > >Then subprograms are the only case where we have special >rules. > > >Such an approach would make the egregiously bad cases >(8 & 9) illegal and, if I had my way, would also make >7 illegal since "a" is a non-subprogram reference. > > > >Anyways, feedback and discussion is clearly welcome on >this. > > >Gord. > > >-- >-------------------------------------------------------------------- >Gordon Vreugdenhil 503-685-0808 >Model Technology (Mentor Graphics) gordonv@model.com 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 TrainingReceived on Fri Aug 26 15:13:06 2005
This archive was generated by hypermail 2.1.8 : Fri Aug 26 2005 - 15:14:28 PDT