How entity name is resolved in architecture body...

T

Tomas Whitlock

Guest
Hi all,

I\'m working on a tool that is supposed to read VHDL and create an abstract representation of a design unit.

I have run into a problem where I\'m trying to understand how this common form of an entity declaration + architecture body is accepted by VHDL compilers such as Vivado Simulator / Synthesis, ModelSim / Questa and no doubt others:

entity e is
...
end entity;

architecture a of e is
...
begin
...
end architecture;

After repeatedly reading the VHDL LRMs of \'93, 2002, 2008 etc., it seems to me that, if the rules are interpreted literally, the entity \'e\' should not be visible to at the point where the architecture body declaration references it.

Yet all of the VHDL compilers that I\'ve ever encountered will happily accept the above VHDL as valid.

The LRM mentions a \"library declarative region\", in which primary design units of that library are visible, but it doesn\'t say where it applies. The LRM doesn\'t seem to leave much room for the library declarative region to be nested within some other declarative region, so I don\'t know what to make of it.

So my question is:

Do most VHDL compilers bend the rules and add some additional rules of their own (for example, adding \"use work.all;\" to the predefined language environment), or am I missing something in the LRM that makes the entities of the work library visible to an architecture body declaration (when being compiled into the same work library)?

Thanks in advance for any insights.
 
Wouldn\'t that code be valid under the specification when you look at default binding indication?

For the VHDL 2000 standard which I just looked thru that would be Section 5..2.2.

The VHDL reference guide webpages (https://www.ics.uci.edu/~jmoorkan/vhdlref/confspec.html - I believe this site is for the 93 standard) sums it up nicely as follows:
\"In the absence of an explicit configuration for any part of a model, default binding will occur. For each unbound instance of every component, an entity will be selected whose name, port names and port types etc. match those in the corresponding component declaration. Where an entity has more than one architecture, the last analysed architecture will be used.\"

This answer is not to imply that the current tools don\'t bend rules when it comes to following the written standard. I cannot answer with confidence if they do or don\'t.
 
On Monday, 30 May 2022 at 23:01:56 UTC+1, patel...@gmail.com wrote:
Wouldn\'t that code be valid under the specification when you look at default binding indication?

For the VHDL 2000 standard which I just looked thru that would be Section 5.2.2.

The VHDL reference guide webpages (https://www.ics.uci.edu/~jmoorkan/vhdlref/confspec.html - I believe this site is for the 93 standard) sums it up nicely as follows:
\"In the absence of an explicit configuration for any part of a model, default binding will occur. For each unbound instance of every component, an entity will be selected whose name, port names and port types etc. match those in the corresponding component declaration. Where an entity has more than one architecture, the last analysed architecture will be used.\"

This answer is not to imply that the current tools don\'t bend rules when it comes to following the written standard. I cannot answer with confidence if they do or don\'t.

Hi Patel,

I appreciate you taking the time to reply, but I don\'t think that section of the standard is relevant to this question, and maybe I haven\'t stated by question clearly enough.

I\'m not trying to understand out how VHDL chooses an architecture for an instantation, but rather: how is entity \'e\' even visible when the compiler encounters \'architecture a of e\'. There are no use clauses in the example I\'ve used and according to the LRM, the only predefined context is \"library std, work; use std.standard.all;\".

So the Root Declarative Region shouldn\'t contain \'e\', and therefore according to the visibilty, scope etc. rules, \'e\' shouldn\'t even be visible and the compiler should error and say so (by my interpretation of the LRM, at least).

It occurs to me that maybe for an architecture declaration, all existing VHDL compilers have a special case *for architecture bodies only* in which the entity\'s name is looked up in the Library Declarative Region as opposed to the Root Declarative Region, and hence \'e\' is visible.
 
Hi,

I have a better grasp of the question you are asking however, do you mind explaining how you get to this assertion you state as true using quotes of the standard to support the assertion:

\"So the Root Declarative Region shouldn\'t contain \'e\', and therefore according to the visibilty, scope etc. rules, \'e\' shouldn\'t even be visible and the compiler should error and say so (by my interpretation of the LRM, at least).\"

It would make the question more clear to me and perhaps to others. Specifically, I am interested as to how you think there would be no visibility of \'\'e\" to the compiler.
 
On Tuesday, 31 May 2022 at 02:23:09 UTC+1, patel...@gmail.com wrote:
Hi,

I have a better grasp of the question you are asking however, do you mind explaining how you get to this assertion you state as true using quotes of the standard to support the assertion:
\"So the Root Declarative Region shouldn\'t contain \'e\', and therefore according to the visibilty, scope etc. rules, \'e\' shouldn\'t even be visible and the compiler should error and say so (by my interpretation of the LRM, at least).\"
It would make the question more clear to me and perhaps to others. Specifically, I am interested as to how you think there would be no visibility of \'\'e\" to the compiler.

Hi Patel,

Ok, here goes with my interpretation of the rules that matter for this case (from VHDL-2002 LRM):

10.1 \"In addition to the above declarative regions, there is a root declarative region, not associated with a portion
of the text of the description, but encompassing any given primary unit. At the beginning of the analysis of a
given primary unit, there are no declarations whose scopes (see 10.2) are within the root declarative region.\"

So this is saying that when starting to parse a VHDL file, the root declarative region has no declarations. Seems pretty obvious. But this is supposed to apply to primary units - but how does the compiler know if it\'s looking at a primary or secondary unit until it has successfully parsed part of it? Surely this applies to all design units, primary & secondary.

It says in 11.2:

\"Every design unit except package STANDARD is assumed to contain the following implicit context items as
part of its context clause:

library STD, WORK ; use STD.STANDARD.all ;\"

So this is how the predefined stuff gets into the root declarative region and is visible. Before the compiler gets to parsing any VHDL code, even context clauses, the root declarative region has only the following visible in it: std (library), work (library) and everything in std.standard.* . Notably, this does not include any entities of the work library such as entity \'e\' from my example.

I believe that if a VHDL file has multiple design units, whether primary or secondary, parsing of each design unit begins with a fresh new root declarative region with nothing in it except the predefined stuff. So after \'end entity;\' of my example, the compiler begins a fresh new root declarative region (not containing \'e\').

I haven\'t found any special case treatment of the entity_name of an architecture body in the LRM, so I conclude that in a literal interpretation of the rules, you should actually need

architecture a of work.e is -- OK: \'e\' visible by selection
....
begin
....
end architecture;

OR

use work.e;

architecture a of e -- OK: \'e\' made visible by use clause
....
begin
....
end architecture;

I guess that in most VHDL compilers, there is a special case where the entity_name lookup for an architecture body is not done within the root declarative region but instead goes to the library declarative region (which certainly does have \'e\' visible). The library declarative region is mentioned in a couple of places in the LRM and nowhere else, so it\'s not exactly obvious what its purpose is or why the LRM even mentions it.
 
On 2022-05-31 03:42, Tomas Whitlock wrote:
On Tuesday, 31 May 2022 at 02:23:09 UTC+1, patel...@gmail.com wrote:
Hi,

I have a better grasp of the question you are asking however, do you mind explaining how you get to this assertion you state as true using quotes of the standard to support the assertion:
\"So the Root Declarative Region shouldn\'t contain \'e\', and therefore according to the visibilty, scope etc. rules, \'e\' shouldn\'t even be visible and the compiler should error and say so (by my interpretation of the LRM, at least).\"
It would make the question more clear to me and perhaps to others. Specifically, I am interested as to how you think there would be no visibility of \'\'e\" to the compiler.

Hi Patel,

Ok, here goes with my interpretation of the rules that matter for this case (from VHDL-2002 LRM):

10.1 \"In addition to the above declarative regions, there is a root declarative region, not associated with a portion
of the text of the description, but encompassing any given primary unit. At the beginning of the analysis of a
given primary unit, there are no declarations whose scopes (see 10.2) are within the root declarative region.\"

So this is saying that when starting to parse a VHDL file, the root declarative region has no declarations. Seems pretty obvious. But this is supposed to apply to primary units - but how does the compiler know if it\'s looking at a primary or secondary unit until it has successfully parsed part of it? Surely this applies to all design units, primary & secondary.

It says in 11.2:

\"Every design unit except package STANDARD is assumed to contain the following implicit context items as
part of its context clause:

library STD, WORK ; use STD.STANDARD.all ;\"

So this is how the predefined stuff gets into the root declarative region and is visible. Before the compiler gets to parsing any VHDL code, even context clauses, the root declarative region has only the following visible in it: std (library), work (library) and everything in std.standard.* . Notably, this does not include any entities of the work library such as entity \'e\' from my example.

I believe that if a VHDL file has multiple design units, whether primary or secondary, parsing of each design unit begins with a fresh new root declarative region with nothing in it except the predefined stuff. So after \'end entity;\' of my example, the compiler begins a fresh new root declarative region (not containing \'e\').

I haven\'t found any special case treatment of the entity_name of an architecture body in the LRM, so I conclude that in a literal interpretation of the rules, you should actually need

architecture a of work.e is -- OK: \'e\' visible by selection
...
begin
...
end architecture;

OR

use work.e;

architecture a of e -- OK: \'e\' made visible by use clause
...
begin
...
end architecture;

I guess that in most VHDL compilers, there is a special case where the entity_name lookup for an architecture body is not done within the root declarative region but instead goes to the library declarative region (which certainly does have \'e\' visible). The library declarative region is mentioned in a couple of places in the LRM and nowhere else, so it\'s not exactly obvious what its purpose is or why the LRM even mentions it.
The WORK library is always visible without it needing to be declared.
Entity \'e\' was compiled into library WORK so it is visible when the
architecture is compiled. I\'ve never seen the USE statement used for
anything other than pulling in packages. \'e\' is an entity, not a
package. I don\'t think the tools are bending the rules in this case.

Charles Bailey
 
On Tuesday, 31 May 2022 at 21:24:43 UTC+1, Charles Bailey wrote:
On 2022-05-31 03:42, Tomas Whitlock wrote:
On Tuesday, 31 May 2022 at 02:23:09 UTC+1, patel...@gmail.com wrote:
*snip* for brevity
I guess that in most VHDL compilers, there is a special case where the entity_name lookup for an architecture body is not done within the root declarative region but instead goes to the library declarative region (which certainly does have \'e\' visible). The library declarative region is mentioned in a couple of places in the LRM and nowhere else, so it\'s not exactly obvious what its purpose is or why the LRM even mentions it.

The WORK library is always visible without it needing to be declared.
Entity \'e\' was compiled into library WORK so it is visible when the
architecture is compiled. I\'ve never seen the USE statement used for
anything other than pulling in packages. \'e\' is an entity, not a
package. I don\'t think the tools are bending the rules in this case.

Charles Bailey

Hi Charles,

Respectfully, I don\'t agree. \'e\' is only visible if the LRM\'s scope and visibility rules say it is. By my reading of the LRM, what is visible at the beginning of compilation of a design unit consists of only: work, std & std.standard.all. That excludes \'e\'.

The VHDL grammar says this:

architecture_body :: architecture identifier of entity_name is
architecture_declarative_part
begin
architecture_statement_part
end [ architecture ] [ architecture_simple_name ] ;

The fact that the entity for the architecture is identified by \'entity_name\' (as opposed to a \'simple_name\') means that it must be subject to the scope & visibility rules like any other kind of name. I don\'t see anything in the LRM to indicate that there is a special case for this entity_name, though I might have missed something. ModelSim accepts \'work.e\' as well as \'e\', indicating that it does indeed treat entity_name as a \'name\', and allows selected names etc.

In the absense of a use clause that makes \'e\' visible, why would it be visible just prior to the architecture body declaration that I used as an example?

Can you explain why you think \'e\' is visible according to the scope and visibility rules? Or do you know of a rule in the LRM that means the usual scope and visibility rules don\'t apply in this case, and instead the compiler just looks in the work library?

I\'m not trying to be argumentative, merely trying to confirm that my understanding of the way the entity name is resolved is correct. I would agree as a practical matter that the way all known VHDL compilers work in treating \'e\' as being visible is for the best.
 
Also, the following VHDL gives an error in ModelSim:

entity e is end entity;

package p is
alias e_alias is e;
end package;

** Error: entity_visibility.vhd(4): (vcom-1136) Unknown identifier \"e\".

On the other hand, ModelSim accepts either of the following without error:

entity e is end entity;

package p is
alias e_alias is work.e;
end package;

OR

entity e is end entity;

use work.e;

package p is
alias e_alias is e;
end package;

Which shows that according to the usual visibility and scope rules, \'e\' is not visible except by selection or by a use clause. So architecture bodies appear to have special case handling for \'entity_name\'.
 
Update: I\'ve now taken a look (I think) at what GHDL does for the \'entity_name\' of \'architecture_body\'. If understand the code correctly, it does this:

If the \'entity_name\' string is syntactically equivalent to an \'identifier\' (i.e. not a selected name or anything like that), then attempt to look it up in the \'work\' library. The usual scope and visibility rules are not applied in this case.

Otherwise, attempt to look up the \'entity_name\' string in the usual way, i.e. look it up in the current declarative region, which for an architecture_body must be a root declarative region. The usual scope and visibility rules are applied in this case.

This seems like a reasonable way to go.
 
@Charles Bailey - Having thought about this some more, I think you are correct to say that implementations are not bending the rules. They are implementing \'entity_name\' resolution as per the rules, but the rules for that particular case are weird and the LRM doesn\'t explain the subtleties well.

I also think there\'s pretty much no way to implement this in a VHDL compiler without treating it as a special case, like the solution used in GHDL.
 

Welcome to EDABoard.com

Sponsor

Back
Top