Re: [sv-bc] Is an unnamed block with declarations a scope?

From: Greg Jaxon <Greg.Jaxon_at_.....>
Date: Mon Aug 15 2005 - 14:18:28 PDT
Steven Sharp wrote:
>>From: Greg Jaxon <Greg.Jaxon@synopsys.com>
> 
> 
>>The specific implementation would involve looking up the incipient
>>label in each of the parent (lifetime) scopes until you reach
>>one which is named.  If none of those scopes has a binding for the
>>name, then it is bound at the level of the named parent.  This leaves
>>just a few open sources where one of the intermediate scopes might
>>also define the name, thereby shadowing it in the inner scope.
>>If declarations and blocks can be interleaved, this might happen.
>>Or if locally defined functions are declared with the same name,
>>there would also be some confusion.  How serious do you think that
>>defect would be?
> 
> 
> While it probably won't come up much in real code, the LRM text
> would have to specify the behavior.  That specification would be
> confusing, even for users who wouldn't run into the situation.  I
> don't think this interpretation offers enough benefits to make
> this possible confusion worthwhile.

Gord started this thread  by pointing out that if unnamed blocks
were "real scopes", this would change the meaning or legality of
certain V2K dusty decks.  The LRM's "Name spaces" section currently
has this backward-incompatible effect.  If cell names in SV suddenly
pick up new hierarchy layers with compiler-generated names, this is
going to be bad for many parts of the flow downstream of the SV tool.

> To make sure that everyone (including me) understands what you are
> saying, here is an example that illustrates what I think you said.

I did mention that shadowing interactions would be the most confusing
aspect of the problem.

> 
> 1)    initial
> 2)    begin:A
> 3)        integer foo;
> 4)        begin
> 5)            integer foo;
> 6)            begin: foo
> 7)                foo <= 0;
> 8)                if (whatever) disable foo;
> 9)            end
> 10)           foo <= 1;
> 11)           if (whatever) disable foo;
> 12)       end
> 13)   end
> 
> This example is unrealistic, but I am trying to keep it concise
> and easy to follow.  Here are some of the questions it raises.
> Some of the things in it are illegal, but under your interpretation
> it is unclear which ones.
> 
> From what you said, block foo on line 6 is declared in scope A,
> not in the unnamed block on line 4.

>  So it [A] appears in a scope outside the unnamed block on line 4.
>  And yet, one expects the disable foo on line 8 to find the block foo
>  declared on line 6,
>  not the integer foo declared on line 5.

>  But if block foo appears
> in scope A, then an upward scope search should find the integer foo
> in the unnamed scope before finding block foo in scope A.  So if
> you want to have the disable find the nearest nested textual foo,
> then the searching rules don't match the nearest scope rules.

> If block foo on line 6 is in scope A, then it conflicts with the
> integer foo on line 3, not the integer foo on line 5.  That implies
> that the integer foo on line 5 is a legal declaration, since name
> conflicts are based on scopes.  So now you try to resolve the
> assignment to foo on line 10 or the disable foo on line 11.  If you
> don't use the scope rules, but try to use an alternate textual
> nesting rule to match expectations, you have a problem.  Integer
> foo on line 5 is at the same textual level as block foo on line 6.
> You don't know which one to resolve it to.  Normally this wouldn't
> arise because two such identifiers would be in the same scope, which
> would be treated as a name conflict.
> 
> The assignment on line 7 was mostly included to give something to
> be disabled from outside (at least in some implementations).  But
> it is also there in case someone tries to specify rules that only
> work for block references.  The assignments appear in the same
> scopes as the disables, and

Here is a key clause:

> the identifier foo must resolve the
> same way for both the assignment and the disable.

I agree that this is most likely true.  The only way your example
could be legal and still sensible would be for this to be false -
that names of blocks and names of variables exist in separate worlds.

Notice that to treat the identifiers' /declarations/ similarly,
we need Gord's proposal (1): every declaration is local to the
innermost enclosing block, whether or not that block is named.
But we've already seen that (1) is not V2K-compatible.  So the
symmetry here is limited at best.

If we can always tell from context what class identifier to seek
then this would not be a big problem, except for the extra confusion
that there are three things named foo co-existing here.  I suspect
that the rules for hierarchical references prevent this line of
development, though.  So what you've written is illegal code;
we could argue about the error message(s); but let's move on.

> I don't know whether you had any rules in mind for how to resolve
> this, but I think anything you try will produce bizarre results
> in some situation.  The only way to get reasonable results is
> to have the scope nesting match the textual nesting and name
> searching.  Your proposed interpretation doesn't do that, which
> leads to problems.
> 
> Steven Sharp
> sharp@cadence.com
> 

Let's assume that block, task, and variable names must share the
same name space.  Here are two simpler variants of your example.
One has a problem under my proposal for (3) that is easily
remedied by using the hierarchical name of the block.  Both have
problems under your concept for proposal (2):

1)    initial
2)    begin:A
3)        integer goo;
4)        begin
5)            integer foo;
6)            begin: foo
7)                foo <= 0;
8)                if (whatever) disable foo;
9)            end
10)           foo <= 1;
11)           if (whatever) disable foo;
12)       end
13)   end

Under (3), lines 8 and 11 cannot disable the block foo unless
they ask to disable A.foo.  Under (2), lines 5 & 6 conflict.

1)    initial
2)    begin:A
3)        integer moo;
4)        begin
5)            integer goo;
6)            begin: foo
7)                goo <= 0;
8)                if (whatever) disable foo;
9)            end
12)       end
10)       moo <= 1;
11)       if (whatever) disable foo;
13)   end

Under (3), the above is legal.  Under (2), line 11 cannot
disable foo, not even if it tries to disable A.foo.
This is more like a real example - no actual name collisions.

I think this RTL makes A.moo and A.foo accessible.
It would also make A.foo.shoo accessible if you declared
shoo at that point in the hierarchy, which I think is
good for v2k compatibility.  Having A.foo.shoo suddenly
change name to become A._unnamed_block%1.foo.shoo just
because you declare A._unnamed_block%1.goo is uncool.

Cases like these won't decide this question, but hopefully
some readers might relate them back to real experience and
help us trade off simple & strict vs complex & promiscuous.

Greg

Disclaimer: Synopsys SV products do not (AFAIK) implement proposal 3.
Received on Mon Aug 15 14:53:17 2005

This archive was generated by hypermail 2.1.8 : Mon Aug 15 2005 - 14:55:29 PDT