Re: [sv-bc] Re: [sv-ec] Updated proposal for 'let' syntax

From: Gordon Vreugdenhil <gordonv_at_.....>
Date: Mon Jun 11 2007 - 07:20:06 PDT
I've tried to narrow this down to just the portions with my
responses.




Korchemny, Dmitry wrote:
[...]

> [Korchemny, Dmitry] The main reason why the hierarchical references to
> "let" were included into the proposal was the desire to keep the "let"
> definition aligned with the definition of sequences and properties.


I'd be willing to step out of this entire discussion if a
"let" was only permitted to be evaluated in the context of
another "let" or in the context of a sequence or property.
Then it really is the same thing and any tool issues are isolated
from the rest of the language.

It is the fact that "let" is *not* restricted in its domain of
application that makes me concerned.


> Another reason was to use it for multiple argument handling, as
> illustrated by the following motivation example from the proposal:
> 
> int args[50:1];
> for (genvar i = 0; i <= 50; i++) begin : b1
>      if (i == 0) begin : b2
>         let res = '0;
>      end
>      else begin : b2
>      let res = b1[i-1].res + args[i];
>      end
>  end
>  let res = b1[50].b2.res;


I really do not understand this as a compelling example.
Why is this any different than "args.sum()" ?  Or a function
that sums "args"?  Or a function in each gen block that
hierarchically calls the other?

What is special about what you are doing here that requires
"let"?


> On to a few direct notes on your response:
> 
>   1) The view the "let" expansion is strictly after elaboration
>      is clearly not accurate, or if it is then the current text
>      is very deficient.  If one has:
>          let x = 10;
>          for (genvar i = 0; i < x; i ++) ....
>      how can one claim that the "let" is after elaboration?
> 
> [Korchemny, Dmitry] I would say that let value should be known before
> usage, i.e., if its value is used for elaboration purposes, then it
> should be evaluated at the elaboration time. Again, if to disallow let
> XMR, then it could be stated that let is evaluated during the
> elaboration.


XMR's are already disallowed here -- Rule 14 requires that since
"x" is constant expression, it is legal only if the equivalent
constant function is legal (i.e. no xmr to "x" and no xmr's
within "x").

That wasn't the point of this in any case -- the point was that
"x" **MUST** participate in elaboration since it is one of
the generate loops bounds.  Mark's contention was that "let"
occurs after elaboration.  If this example is legal, clearly
that contention is not correct.  If this example is not legal
then the proposed rules are deficient in that this is permitted
by the rules.


> BTW, your example suggests that let is a generalization of genvar, and
> maybe these two constructs may be united. What do you think?


No -- "x" in this construct is not a genvar at all -- it is a
constant expression that happens to be a "let" evaluation.


> ---
> 
>      Even in the context of types and type parameters this
>      can occur (at least it isn't currently restricted):
>          let x = 5;
>          type(x) y;
>          M #(type(x)) m();
> 
> [Korchemny, Dmitry] I don't see any issue here. It is equivalent to
> 
> type(5) y;
> M #(type(5)) m();


Again, it just means that "let" participates in elaboration in all
sorts of interesting ways.  You *cannot* insulate "let" from elaboration
if you claim that these are legal.


> 
> ---
>      or even
>          class C (type T = int); ....
>          let x(y,z) = C#(y)'(z)
> 
> [Korchemny, Dmitry] Same idea here.


Really?  Note that "y" here must be a *type*.

I don't really think this would be legal in any case since the grammar
restricts a let actual to being an expression.

But one could have a partially mixed expression --
    typedef int y;
    let x(z) = C#(y)'(z);

Now you don't know whether C#(int) exists until you know whether the
"let" is actually used.  This also causes a specialization that
is a mix of local and remote references.  If this is within a class
and "y" is a local typedef, there isn't even a legal corresponding
source expression.


> ---
> 
>      All of these have non-trivial elaboration impact and
>      seem to be legal in the current proposal.
> 
>      Along the same lines, if "let" is post-elaboration, why
>      is there any restriction about "existence prior to reference"?
>      What does that mean in terms of elab interaction?
> 
>      Is the following legal:
>          for (genvar i = 0; i < 5; i++) begin : b
>             if (i < 4) begin:c
>                let x = b[i+1].c.x
>             end else begin:c
>                let x = 0;
>             end
>          end
>      Does iteration i+1 "exist" at the time iteration i has its
>      "let" defined?
> 
> [Korchemny, Dmitry] My guess is that this should be illegal. If we
> disallow "let" XMR, the issue becomes irrelevant. 

I agree, without XMRs this is trivially illegal.  That is why I
made that suggestion; it gets rid of many problems.

> If we want to allow at
> least the use cases as in the above motivation example, there is a need
> to provide formal semantics of "generate" statements - then we can
> formally define what "existence prior to reference" exactly means.

NO!!!!  That is *exactly* my point.  By intent, Verilog talks about
relationships between objects and *results* of elaboration.
Requiring an *operational* model for generates would severely constrain
implementations and would likely make various general flows that
tools support considerably weaker.


>   4) An additional thought -- one of the key uses for "bind"
>      is to allow assertion instances to bind into otherwise
>      "pure" rtl.  How does one "bind" an instance which includes
>      a "let" expression into a target?  Clearly (I hope!) one can't
>      do the syntactic form of expansion that is being suggested.
>      Is that illegal?  Is it just something that no tool will
>      be able to implement?
> 
> [Korchemny, Dmitry] Could you provide a specific example? It is legal to
> bind instance with sequences and properties.


It isn't the *body* that is the problem, it is the *actuals*.
    bind top.mid.bot M m(a,b,c);

What is "a" is a "let" that is defined in "top.mid.bot"?  In order
to use the "let" in the macro-like manner that is being proposed,
one would have to defer way too much until "bind" time.  In particular,
if "let" can create new class specializations, you would have to
deal with that interaction at bind time.

Requiring this would break very important tool flows where "bind"
occurs very late -- well after the target (typically the dut) is
compiled.  I really do not think that the user community would
be happy with that.

[...]
>>>    5)  ... In the scope of declaration, let must be defined 
>>> before used.
>>>    6) The let expression is inlined ....
>>>    7) The let expression can be referenced by hierarchical name...
>>>
>>> Given:
>>>     module top;
>>>        int x = some_non_existent_module.some_let_name;
>>>     endmodule
>>>
>>> How does one inline the let expression in the presence of 
>>> separate compilation?  Clearly one cannot.
>>>
> [Korchemny, Dmitry] This is not different from the case of sequences and
> properties.


(1) - if you want to make implementation assumptions within the assertions
       sublanguage, I don't care too much.  I do care if those assumptions
       bleed over into the core language.  I think the assertions assumptions
       are fundamentally flawed and don't lead to large scale efficient
       design unless there are vendor restrictions.  Such restrictions are
       not going to be the same for every vendor and will be frustrating
       to users.

(2) - My comment was that requiring "inlining" and "declaration before use"
       is fundamentally at odds with the hierarchical name assumptions
       in Verilog.


>>> Any statement of "inlining" is incomplete and not possible in 
>>> a general Verilog design.  Any requirements for inlining in 
>>> the presence of hierarchical names are in conflict with the 
>>> rest of the LRM semantics and must be struck or be 
>>> well-defined in terms of the **elaboration** model.
>>>
>>> (5) also directly conflicts with (7).  If (7) is true, then 
>>> the following is legal:
>>>     module top;
>>>        int x = top.y;
>>>        let y = 0;
>>>     endmodule
>>> But (5) just claimed that you cannot refer to the let before using
> it.
> [Korchemny, Dmitry] Again, the same situation happens with sequences and
> properties


So, why is there any "declaration before use" requirement whatsoever?

If all of these follow full Verilog rules then you should not be
trying to explain the name binding.  If there are special restrictions,
talk about them.


> [Korchemny, Dmitry] This issue is not specific to XMR, you could put the
> let definition into the same module. If the syntax is overloaded, it is
> what we will get. Consider a more likely example:
> 
> module top;
> 	let f(x,y) = x + y;
> 	bit [5:0] a, b;
> 	bit [6:0] c, d;
> 	... f(a,b)...
> 	... f(c,d)...
> endmodule
> 
> Here also the f(a,b) and f(c,d) represent different opeartors, therefore
> the question is whether the operator syntax is overloaded on purpose or
> not. One could limit the "let" definition to allow only expressions of
> integral type - this would filter out such cases of "wild" overloading.

This is a much simpler example -- the *operations* are still
arithmetic, just the widths are different.  Having the *semantic
meaning* of a token change in a "let" expansion implies a really
nasty implementation model.


> On the other hand this limitation may be unnecessarily restrictive.

That depends on your assumptions.

If you are going to *require* a source-level implementation model, then
you are assuming that ALL SOURCE is available at the time of design
elaboration.  I really don't think IP providers, etc. are going to
be very happy about that.  That also wreaks havoc with large scale
separate compilation.

Of course vendors can (and will) restrict such behavior, but do
you really want to be adding things to the language that are
specified in such a way that there will necessarily be vendor
restrictions, etc.?  I do not see that as being a good approach
to language design.

> [Korchemny, Dmitry] You are right, this definition is missing. I think
> that let should be part of package_or_generate_item_declaration.
> Therefore the above example should be illegal.


Ok, that deals with the "class" example.  By construction then, one
also cannot have a "let" inside a sequential block, right?

Gord
-- 
--------------------------------------------------------------------
Gordon Vreugdenhil                                503-685-0808
Model Technology (Mentor Graphics)                gordonv@model.com


-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Mon Jun 11 07:20:48 2007

This archive was generated by hypermail 2.1.8 : Mon Jun 11 2007 - 07:21:04 PDT