Re: [sv-bc] Question about of section 7.13 of 1800-D3

From: Greg Jaxon <Greg.Jaxon@synopsys.com>
Date: Fri Jan 28 2005 - 12:07:49 PST

Francoise Martinolle wrote:
>
> Greg,
>
> Thanks for the explanation. Your new text is wordy but a lot more clear.
> Can we get this new text in the LRM?
>
> Francoise

Yes, but after checking my text against the rest of the LRM and my notes on
sv-bc discussions, I see that my replacement text did not decompose the
cases exactly right.

Notice that when introducing array construction, the LRM currently says:

"Verilog uses concatenation braces to construct simple bit vectors.
  System Verilog extends that syntax to support the construction of
  unpacked arrays and multidimensional packed arrays.
  Unlike in C, the expressions must match element for element and
  the braces must match the array dimensions.
  Each expression item shall be evaluated in the context of an
  assignment to the type of the corresponding element in the array...."

             One point often raised when this is discussed is that
             "construction" semantics *are* the SV extension.
             So I was wrong saying "packed" vs "unpacked" can
             distinguish concats from constructors. Instead,
             the focus shifts to "simple bit vector" vs "multi
             dimensional packed array" and all else new in SV.
             (i.e. original Verilog vs System Verilog).

The whole point of having any substructure within a datatype is so that
your access methods can be guided by it. Concatenation is simply
the wrong way to be building multidimensional packed arrays. It violates
the expectations set up by our introductory paragraph. These types should
use construction semantics by default.

In dealing with arrays, we have let the assignment compatibility rules
ruin our intuition about which things are the basic elements. Instead we
should see that multidimensional arrays are built up as a hierarchy of
lower dimensional subarrays - beginning not with the "bits", but with
the "simple bit vectors" of Verilog, to which SV adds a few builtin types.
(This is the only compromise made obviously for Verilog compatibility.)

We also let the phrase "type equivalence" fool us into thinking that
equivalent types must be fully interchangeable. When you use a context
sensitive syntax in two different settings, it *can* change its meaning.
Equivalent types are not necessarily going to have equivalent effects
on curly braces: each type imposes on the braces its own fine substructure.
Language designers have often shunned designs that present such surprises.
But the authors of Verilog and System Verilog were not so inclined.
(Witness the context-determined expression bit width rules.)

Array construction syntax reflects this model of arrays and uses all
of the substructure of the datatype. This shows up in several areas:

Construction by association:

   - When "index:value" is used, the singleton index addresses
     the topmost dimension in the hierarchy - for a multidimensional
     packed array that is the leftmost index range given in
     the type declaration.

   - When the type in "type:value" does not match the top level of
     the hierarchy, it recurses into the next level. Recall that
     our type matching rule requires that all substructure be conformal.

   - And finally "default:value", described entirely in terms of
     "elements" has so far only been used to coerce and replicate
     some simple bit vector into each of the "leaf" elements of the array.
     (I'd like once again to suggest a refinement of this, but we are
      no longer at that stage of discussion.)

Construction by enumeration:

   - The braces used in a nested list structure must express the
     substructure of the array.

   - When we get to the simple bit vector elements, the braces revert
     to concatentations. Since lists of 1 bit values would be
     pointlessly tedious.

Explicitly-typed array construction:

   - When the explicit type given in the form "type'{}" is multi-
     dimensional array (packed or unpacked) the braces are read as an
     array constructor.

   - When the explicit type is a simple bit vector, or
     an explicit size value, or either of the signing keywords, then
     the braces are read as concatenation.

So where does all this leave the original paragraph?
Currently the LRM says:

"SystemVerilog determines the context of the braces when used in the context
  of an assignment. If used as the right-hand value in an assignment to
  an unpacked array, the braces represent an [unpacked] array constructor."

In the erratum, the word [unpacked] vanishes. But I believe that this
editing direction went off-target just a bit. As the argument above indicates
This sentence should have read:

"If used in an assignment-like context to an unpacked _or_multidimensional_
_array_, the braces represent an array constructor."

The next sentence:
"Outside an assignment-like context, an explicit type prefix must be used
(see 3.14)."

... is as Brad said, just redundant. Especially if you accept my
wordsmithing of the prior sentence so that it also applies to all
"assignment-like contexts" instead of the original.

Taking one more pass at this poor abused text, I think the first sentence
is muddled. So the fully revised paragraph should say:

    "SystemVerilog extends the meaning of braces when they are used in
     the context of an assignment. If used in an assignment-like context
     to an unpacked or multidimensional array, the braces represent an
     array constructor. Outside an assignment-like context, an explicit
     type prefix must be used to distinguish array construction from
     Verilog concatenation (see 3.14)."

When the text settles into this groove, there is much less demand
for the '{} form to indicate construction. {}s are just context
sensitive, and they pick up on any SV structure you add to your data.

------------------

* At this juncture I am going to make one last appeal in regard to
   this recursed "default:value". When constructor syntax was extended
   beyond unpacked types, the definition of "default:value" as then
   written fell apart. It has been so hard to discuss and think about
   that I feel it has remained broken in one important respect. It
   is not yet sensitive to the SV type of the value.

   The job of a default clause is (more than most other syntax) to read
   the user's mind. I think this requires picking up on every clue
   he gives us regarding what he'd like done with the value. Most
   packed values have no structure whatsoever, except that they are
   simple bit vectors of some width TBD under the assignment context rules.
   BUT a variable, or an explicitly cast expression can have a complex
   System Verilog data structure. I think it is a gross mistake to
   ignore this, and truncate or extend it to jam it into every simple bit
   vector in the resulting object.

   When talking about the types of packed data, we come up against
   the context-determined bit width rules, which many folks expect will
   apply to the default assignments when they finally occur.

   But BEFORE the assignments are layed out, the constructor first has
   to match this clause with some subset of the object being constructed.
   In considering how to do that, I believe that SV data structure should
   take precedence. We're certainly not going to MATCH by sheer bit width,
   since the assignment rule says that bit width is supposed to yield to
   the size to which it is assigned. But we can match by using the
   SV type of the value (which we can know independent of and prior to
   te application of any assignment coercion). And if a match is found
   to some part of the object substructure, then NO COERCION is necessary.
   I think that by itself indicates that we read the user's mind!
   And if it never matches? Well by then you've recursed to the simple
   bit vector level, and the existing rule will continue to work just
   as it does today.

   Originally the 3.0 text on this subject said that the default would
   apply to everything to which it could be assigned. But for packed
   data, the assignment rules are too permissive. The new type matching
   rules seem right, but seem too strict when it comes to the
   simple bit vectors.

   So I urge the LRM to alter its text (in 7.13 & 7.14) as follows:

   - For default:value, if value has a simple bit vector type, it will
     be used for each simple bit vector element of the array or struct
     not otherwise covered by the rules of this section. It is evaluated
     once in the context of an assignment to the array element (struct field)
     type. If value is a multidimensional array, or any unpacked type,
     then it will be used for each (field) subarray along the trailing
     dimensions whose type matches the type of the value, it is evaluated
     once and no coercions need be applied. Note that the value expression
     in default:value is not an assignment-like context.

   I believe this accomodates packed arrays and structs of enums.
   without reducing the set of things currently parsed by 3.1a. It
   prevents packed structs from losing their structure in a coercion
   unless the author inserts an explicit cast. As with all changes
   to this deep recursion, it is slightly incompatible with most earlier
   proposals, but from my experience with a maturing implementation,
   it seldom gives a rude surprise. Mostly I like that it respects
   any SV structure the designer has established.

Greg Jaxon

Greg Jaxon originally replied to Francoise:
>
> "When an assignment-like context imposes a packed array type on curly braces
> there is some ambiguity about whether their contents are to be interpreted
> as a self-determined concatenation of bits, or as context-determined elements
> of an array. When the braces enclose a list of index, type, or default keys,
> they have no interpretation as a concatenation, and so are treated as an array
> constructor. When braces enclose an expression_list, or a multiple
> concatenation, then they continue to be regarded as concatenation. As in
> Verilog, such expressions are self-determined and do not inherit any type
> information from the assignment-like context. Although packed array
> construction does not happen by default, it can be forced by using an
> explicit type-prefix. When
> the
> left curly brace has a type prefix and introduces a list of expressions,
> or a
> multiple concatenation, it is a constructor even if the type identifies a
> packed
> array. In this case, the expressions are assigned element-wise to the
> bits or
> to the subarrays along the first dimension of a packed multidimensional
> array."
>
> I apologize for the wordiness, hopefully this level of redundancy will
> prevent mistakes in the use or implementation of this troublesome language
> feature.
>
>
>>What about if the vector data object does not have a explicit data
>>type (look at mdv1 declaration in the examples below)?
>>Perhaps the intent of this last sentence is to determine if curly
>>braces in the absence of an index, type or default key mean a
>>concatenation of an array constructor. But it is not always possible
>>to have an explicit type prefix if the data type of the object is
>>implicitly declared with ranges. In that case the curly brace will
>>always be interpreted as concatenation.
>>Additionally this rule should also apply to multi dimensional packed
>>arrays and not just simple vectors.
>
>
> I agree. But note that since the constructed type is "packed", the
> assignment can proceed even when the constructed type isn't precisely the
> same one which declared the receiving object. So any equivalent packed
> array typedef ought to do the job...
>
>
>>ex: I think that all the following assignments are legal and none
>>require a explicit type prefix
>>
>>logic [1:0] [2:0] mdv2; // 2 dimensional packed vector
>>
>>logic [2:0] mdv1; // simple bit vector
>>
>>// use of index or default keys
>>mdv2 = {2:2'b1, 1:2'b0, default: 2'bx};
>
>
> Yes, this is going to be an array constructor. But No, you've written a
> statement with an out-of-bounds index and implicit 0-extension of
> each element. I think the "first" index here is [1:0]. Your example
> would be correct had you declared logic [2:0] [1:0] mdv2;
>
>
>>
>>// use of replication in array constructors for packed array
>>assignment
>>
>>mdv2 = {3{2'b1}}; equivalent to {2'b1, 2'b1, 2'b1} ?
>
>
> No, this would not be an array constructor. It is just plain old
> concatenate.
>
>
>>
>>// use of array constructor for a simple packed vector
>>
>>mdv1 = {default: 1'b0}; equivalent to {1'b0, 1'b0, 1b0} ?
>>A more interesting example for mdv1 would be:
>>mdv1 = {default: 3'b000}; which is equivalent to {3'b000, 3'b000,
>>3'b000} which assigns the value 3'b000 to mdv1
>
>
> Right, but only because 3'b000 is truncated to 1'b0 when it is assigned to
> the corresponding array element of mdv1.
>
>
>>
>>or
>>
>>mdv1 = {3'b000, 3'b111, 3'bxxx} which is a concatenation and assigns
>>3'bxxx to mdv1.
>
>
> Right again, the most significant bits are truncated, and this is Verilog
> concat.
>
> I think we mostly know what to expect from this syntax now.
> It strains my personal limits for syntax ambiguity, but I'm pretty
> conservative. Heck, the world just loves Perl, and I doubt more than a
> handful of Perl users can correctly parse some of the monstrosities that are
> legal in that language... so this will probably survive the test of time.
>
> Greg Jaxon
>
>
>
>
Received on Fri Jan 28 12:07:59 2005

This archive was generated by hypermail 2.1.8 : Fri Jan 28 2005 - 12:08:03 PST