John,
> My point is that types have no utility in a language
> except to determine ho memory is allocated -- how
> it is organized, in the case of data structs.
Memory allocation is not the only purpose. In a strongly
typed programming language the type system serves to catch
programming errors. SV enums are strongly typed in this way.
Defining the type (or type and subtype, in vhdl terms) of every
expression can lead to corner cases. For instance, vhdl
defines the bounds and direction of every range in an array
expression. This information can be extracted by a vhdl function:
function lefts(x : std_logic_vector) return integer is
begin
return x'left;
end;
function leftb(x : bit_vector) ... etc.
You can define similar functions to get the right bound and the
direction of an array. Now you can call this function with arbitrary
array expressions:
lefts((3 => '1') & "11") -- vhdl concat operator
lefts(not "11")
leftb(not "11")
The rules for computing the bounds of a concat operator changed from
vhdl-87 to vhdl-93, meaning that the lefts function could return a
different value. And for some reason the rules for the bounds of
"not" are different for types std_logic_vector and bit_vector, so the
above calls to lefts and leftb of the not expression have different values.
The rules for null arrays such as "" also cause problems.
These wonderfully precise type rules in vhdl are a source of corner cases.
Corner cases provide job security for tool developers, but they are not
good for language users.
Paul
----- Original Message -----
From: "John Michael Williams" <jwill@BasicISP.net>
To: sv-bc@eda.org
Sent: Thursday, June 17, 2010 2:01:04 AM
Subject: Re: [sv-bc] Type of a concat expression
Hi Steven.
My point is that types have no utility in a language
except to determine ho memory is allocated -- how
it is organized, in the case of data structs.
Advanced languages such as Unix shells or Tcl handle memory
allocation automatically and do not require types.
If the memory allocation for a concatenation is well determined
by its components, then it doesn't make sense to me
to care about its "type". One defines a concat; one
does not declare it.
I agree that one can ASSIGN a type to a concat which will
not alter its properties, but this is CASTING the concat,
or perhaps testing the concat to see what would happen if it
were cast, not deducing some sort of implied declaration
equivalent to the concatenated components.
Applying type() to an object should return a name for what
it was declared as. If it was not declared, then it
should return some sort of null, for example the null string "".
Please read below.
On 06/16/2010 04:34 PM, Steven Sharp wrote:
>
>> Date: Wed, 16 Jun 2010 15:13:04 -0700
>> From: John Michael Williams<john@svtii.com>
>
>> Maybe so, but expressions don't have any "self-determined" result
>> type, because expressions aren't declared.
>
> I am not sure what your point is here. An expression has a collection
> of properties that determine the values it can take on, how those values
> are interpreted, and what types that expression is compatible with. That
> corresponds rather closely to the concept of a type, and the rest of us
> are calling that the type of the expression. It is perfectly reasonable
> terminology.
>
> The type of a particular expression in Verilog source code may be
> dependent on the context where it appears. If it is in a context where
> it is not affected by the context, it is called "self-determined". If
> we want to talk about these properties without having to account for
> the context, we can talk about the properties when the expression is
> self-determined.
I agree that the properties can be self-determined. But this is
not equivalent to applying the type() operator to it to discover how
it originally was declared. Expressions are not declared.
Perhaps the type() operator should be replaced by a "type_compatible()"
operator; if this were done, then the result would be in accordance
with your justification above, and I would not have any objection.
>
>
>> Similarly,
>>
>> bit a;
>> logic[3:0] b;
>> reg[3:0] A, B;
>>
>> compare a = A& B; to b = A& B;.
>
> They have different types. That is fine, since they are different
> expressions. They appear at different places in the source code,
> with different contexts. They happen to be represented with the
> same characters, but they are not the same instance of an expression.
>
> You seem to be trying to discuss the type of some abstract concept of
> an expression that is independent of its context in the source code,
> instead of the type of specific expressions in the source code. You
> can't do that in Verilog.
>
> In fact, you can't do it in other languages either. Expressions
> represented with the same characters may have different types in other
> languages too, if they appear in the different context of different
> scopes where the names refer to different variables. I'm sure you have
> no problem accepting that kind of context-sensitivity, so I don't know
> why this kind is giving you trouble.
>
> There is actually a way in which you can discuss the type of an expression
> in Verilog in a more abstract way, independent of the exact context in
> which the expression appears (but dependent on scopes of course). That
> is to discuss what type it would have in a self-determined context. Which
> is why the LRM talks about the self-determined type of an expression.
>
>> "type( A& B)" is meaningless.
>
> It is perfectly meaningful. It tells you the type of that expression in
> that context. And since an operand of the type operator is self-determined,
> it tells you the self-determined type of the expression. It doesn't tell
> you the type of a similar expression appearing in a different context, such
> as an assignment to b. I don't know why you think that makes a difference,
> and renders this meaningless.
>
> Actually, if we are going to be pedantic here, the type operator doesn't
> "tell" you anything. It has certain behavior when it appears in the source
> code, and that behavior can be described without saying that an expression
> has a type. If it is used in a comparison, it compares the properties of
> the expression with the other side of the expression, to see if they satisfy
> the rules listed for matching types. If the LRM specifies this behavior
> for an expression, then this construct is meaningful, whether you consider
> an expression to have a type or not.
>
> Your reference to type() returning an empty string suggests that you have
> confused it with $typename(). That does actually "tell" you something.
> The description of $typename() in 20.6.1 definitely allows expressions,
> and definitely says that the expression has a type. It describes what
> to return based on that type, and it is not an empty string.
>
> If you are unable to accept the meaning of the term "type" as it is being
> used in the LRM, and use that to understand the specified behavior for
> type() and $typename(), that is not the fault of the LRM. Terminology
> means what it was defined to mean in this context, even if that does
> not match a meaning you are accustomed to elsewhere.
>
>
> Steven Sharp | Architect | Cadence
>
> P: 508.459.1436 M: 774.535.4149 www.cadence.com
>
>
>
-- John Michael Williams jwill@BasicISP.net -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean. -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.Received on Thu Jun 17 06:01:24 2010
This archive was generated by hypermail 2.1.8 : Thu Jun 17 2010 - 06:03:42 PDT