Re: [sv-bc] Union assignment patterns

From: Greg Jaxon <Greg.Jaxon_at_.....>
Date: Tue Feb 28 2006 - 10:49:29 PST
Under the assumption that LSBs align, and that no bits
other than those of the assigned datatype will be changed
it looks like several of the alternatives yield the
same result.  Specifically, assigning the same value
to an LSB-aligned union of two different widths is going
to have the same effect as assigning it once to the
largest width.  (I'm thinking only of integral types here.)

   I wasn't willing to assume much about
union layout, so I just wrote out all the candidate
definitions to think about what they might mean.

   As for the default:value case...
Here we only need to consider RHS assignment patterns.
When a union type field (in the LHS) is a candidate match
for a default specifier there are two possibilities to start.

  1) The value may have the matching union data type.
     - in this case the assignment is done in the obvious way.
  2) If the value is not the matching union type, the pattern's
     type- and default- specifiers shall be used recursively on
     all the fields of the union data type, with the requirement
     that at least one of them must match some field.   One or
     several assignments are made as a result.

Unions offer more opportunities for ambiguous outcomes, and
I'm not sure whether it is our problem to disambiguate these
cases.  A union is not a great choice of datatype when
specifying an essentially type-driven language feature.

There are two principles controlling the operation of
assignment patterns.  When we're trying to "match" fields
with expressions to assign, there is a precedence that
puts names, indices, types, and defaults into that order
as a hierarchy.  But for example, between two type
specifiers, there is only a lexical order, and we say
that the last wins - which is like saying both happened
and the last survived.  So the question is how should
we behave as we traverse the fields of the union?  If one
field is going to match by type, shouldn't that take precedence
over other fields that might happen to fill by default?
For a union, once we get ONE field to match, why should
we blunder on trying to overwrite it?  Should the declared
order of the union affect this outcome?

I think the Name, Type, Default hierarchy takes first
precedence.  A field of union type has been "matched"
if:
   1) A Name-specifier matches a field of the union, or
      failing that
   2) A Type-specifier matches the type of one (or more)
      union fields, or failing that
   3) A Default-specifier has a value whose type matches
      one or more of the union fields.
Filling of the union stops after a match at any of these
steps, but within a step if there are multiple possible
matches we have to use some arbitrary conventions to
decide which bits get clobbered.

Compounding all those assignments is kind of a mishmash.
If there are too many, from competing type- or default-
specifiers, you get what you get, and the best we can say
is that if you read the last field we wrote, you'll see the
value of the final matching clause.  Since there is no
sensible "better way", I'm fine with either leaving it
undefined, or arbitrarily fixing the order that union fields
are visited.  We already have the lexical order of the type-
and default- clauses, so tell the users to "do the math"
as the expression goes.   A warning as soon as the compiler
finds a second match (at some level of the hierarchy above)
in a union traversal is a Really Good Idea.

I'd rather leave that warning up to the implementation,
because there are some subtle things you can do to accommodate
cases like Francoise noticed - where the outcome is the same
either way. Why ruin their day warning about non-problems?

Greg Jaxon


Francoise Martinolle wrote:
>  
> Greg,
> 
> I do understand your proposal except the default:value case. I see that if
> we apply the default:value
> rule, more than one union member could be candidate of the assignment of the
> value. 
> It seems that you imply that all candidates are assigned and the last
> matchable member assignment 
> wins?
> Why would this be different from the positional association of an integral
> value - your choice 
> there is the largest member of the union.
> 
> Francoise
>     '
> -----Original Message-----
> From: owner-sv-bc@eda.org [mailto:owner-sv-bc@eda.org] On Behalf Of Greg
> Jaxon
> Sent: Monday, February 27, 2006 5:48 PM
> To: francoise martinolle
> Cc: sv-bc@eda.org
> Subject: Re: [sv-bc] Union assignment patterns
> 
> Francoise Martinolle wrote:
> 
>> 
>>Unions are problematic, I would prefer not to allow them.
> 
> 
> But of course they turn up deeply nested sometimes.
> 
> 
>>By the way, I do not see anything in the LRM specified for an 
>>assignment pattern to a struct containing an union type member. So 
>>what is the behaviour?
> 
> 
> You're right, the LRM wording has side-stepped plain unions.
> I believe that was an oversight, because most of the required behavior is an
> obvious extension of the rules for structs.
> First, it should be obvious that the union type is imposed by the assignment
> context upon the '{...} assignment pattern.
> 
> In the following discussion, I use the term "value" to mean both "data
> object" and "variable lvalue".  Each of these has a definite data type at
> the elaboration stage where assignment patterns become resolvable.
> 
> Within a union assignment pattern, name:value clauses are not a problem.
> Type:value clauses are also not a problem, unless we must quibble about
> WHICH of the overlaid fields of that type is being assigned.
> Default:value clauses that descend into a union are certainly special;-)
> Recall that the matching rule for default assignment is that it should fill
> fields whose types match the value's.  I think that works for unions too,
> analogous to the way type:value patterns work.
> The burden of filling "every" field of a struct converts to filling "at
> least one" field of a union.  I think the "last assignment wins"
> rule used elsewhere is the right resolution for multiple union fields being
> assigned.
> 
> The extra verbiage needed to cover these cases?  Try adding "and/or union"
> wherever "structure" is mentioned in 8.13.
> 
> The tough issue with assignment patterns for unions is the treatment
> of positional aggregations, such as '{0} or '{1{0}}.   Obviously,
> we only need ONE value (or lvalue) to fill a union.  We must decide which
> field to use in making the assignment, because its declared type will
> influence the final bit pattern produced.
> 
> A) Since this issue is notational, and not something that arises at
>     runtime, it could be a syntax error.
> 
> However, there are two reasonable definitions that might work:
> 
> B) Perhaps a positional list that comes into correspondence with
>     a union object should be required to contain EMPTY list positions,
>     one for each field NOT assigned, and exactly one position with a
>     value corresponding to the union field that will be assigned.
>     It's odd; but also satisfyingly punitive to those who try to cut
>     corners using unions.  This preserves the ability to use
>     nested assignment patterns to pick up the declared type of the
>     union field at each list position.  Recall that positional assignment
>     patterns for structs correspond to the struct's fields in declared
>     order.  This order gives us nested assignment-like contexts where even
>     more assignment patterns can be written.
> 
> C) Only one value can be listed positionally; it will either be
>     strongly typed or it will be integral.  It CANNOT be an assignment
>     pattern, since there either are or potentially could be several
>     incompatible types with equal claim to this context.
> 
>     If it is strongly typed, use its type to find the top-level field
>     of the union which matches (but unlike default:value, DO NOT RECURSE
>     into any substructure of the union elements looking for a match).
>     If it is integral, then we should be prepared to match top-level
>     fields of any packed type.  There might be several.  They may differ
>     in signedness and width.  Their signedness does not matter, since it
>     will not affect extensions done to assign the field.  Their width is
>     relevant, though.  The candidates for breaking this ambiguity are:
> 
>       1) Use the first integral type field in the union.
>       2) Use the last.
>       3) Use the largest.
>       4) Use the smallest.
>       5) Use a (possibly synthetic) integral type whose width is
>          the total size of the union.
>       6) Use the smallest which covers the width of the supplied
>          (positional) value.
> 
>     Of the choices for option C, I'd say (3) "the largest" is the wise
>     choice.  I don't care for (5), because it seems to give us a definition
>     even if there is /no/ integral type field in the union.  (6) might be
>     annoying.
>     Notice that if the union is laid out with the LSB of all integral
>     type fields aligned, then (3) sets all the bits so that accesses
>     to the smaller fields effectively truncate as the original assignment
>     would have truncated.  This gives maximal preservation of semantics
>     and syntax when an integral type field gets converted to a union
>     of integral types and not all the assignment patterns that use it
>     get rewritten.
> 
> So the choice of A, B or C, and within C of which way to resolve the
> ambiguity, can be subject to a vote.
> 
> Greg Jaxon
> 
> 
> 
>>I see that we have allowed struct pattern assignments to tagged unions 
>>see section 8.14.
>>
>>Francoise
>>    '
>>
>>-----Original Message-----
>>From: owner-sv-bc@eda.org [mailto:owner-sv-bc@eda.org] On Behalf Of 
>>Greg Jaxon
>>Sent: Monday, February 27, 2006 1:46 PM
>>To: francoise martinolle
>>Cc: sv-bc@eda.org
>>Subject: Re: [sv-bc] Aggregate / struct - 2 questions
>>
>>That's a compelling idea, Francoise.  For structs, I think 
>>member:value notation would be even better (or a format option).
>>Perhaps you could also imagine a way to handle union types?
>>I suggest displaying each union in ALL its possible interpretations.
>>Since this can exponentially explode the amount printed, it may 
>>discourage use of (non-tagged) unions.
>>
>>Your plan amounts to a default definition for the to_string()
>>class method that Jonathon suggests.   Perhaps it should be provided
>>as both a format notation and a built-in method for any user-defined type.
>>
>>I don't recall seeing a $display format that explicitly made Verilog 
>>numbers before.  That seems like an adjunct to providing this capability.
>>
>>Greg
>>
>>
>>Francoise Martinolle wrote:
>>
>>
>>>How about creating a new format which would return the aggregate 
>>>constant value for the struct by displaying the struct aggregate value 
>>>using the positional aggregate form and default formats for each 
>>>member type.
>>>Ex:
>>>
>>>typedef struct {
>>>   bit  [3:0] dst_addr;
>>>   bit  [3:0] src_addr;
>>>   bit [31:0] data;
>>>   bit  [7:0] crc;
>>>} pkt_s;
>>>
>>>$display("pkt1 = %a", pkt1)
>>>
>>>pkt1 = '{4'b0, 4'b0, 32'b0, 8'b0}
>>>
>>>We could be defining a default format for datatype, unless there is 
>>>already an existing mapping.
>>>
>>>Francoise
>>>   ' 
>>>-----Original Message-----
>>>From: owner-sv-bc@eda.org [mailto:owner-sv-bc@eda.org] On Behalf Of 
>>>Clifford E. Cummings
>>>Sent: Monday, February 27, 2006 12:55 PM
>>>To: sv-bc@eda.org
>>>Cc: nikhil@bluespec.com; Brad Pierce; matthew.r.maidment@intel.com
>>>Subject: RE: [sv-bc] Aggregate / struct - 2 questions
>>>
>>>Brad, Matt & Nikhil -
>>>
>>>Question for the three of you below.
>>>
>>>Other comments included.
>>>
>>>At 08:44 AM 2/27/2006, Jonathan Bromley wrote:
>>>
>>>
>>>
>>>>>Is there some way to unpack the struct (almost like aggregate
>>>>>de-assignment) so that the display command could be written 
>>>>>something
>>>>>like:
>>>>>
>>>>>$display("dst=%h src=%h data=%h crc=%h", pkt1);
>>>>
>>>>I personally don't think this is a very good idea.
>>>>
>>>>If the struct were packed, as is likely for synthesis, then you 
>>>>couldn't reasonably do this (because the packed struct also has a 
>>>>perfectly good integer value when taken as a whole).
>>>>This could lead to all sorts of hideous ambiguity; how about this... 
>>>>(p2 is of the same type as pkt1):
>>>>
>>>>$display(
>>>> "pkt1=%h, p2.dst=%h p2.src=%h p2.data=%h p2.crc=%h",
>>>>     pkt1, p2);
>>>>
>>>>How could $display work out which %h is associated with what?
>>>
>>>
>>>I was hoping there was some undiscovered piece of magic, perhaps using 
>>>one of the streaming operators, that would take each field of the 
>>>struct and parse them out in struct-order to the respective %h format 
>>>specifiers. I did not really think it existed but sometimes I ask 
>>>these questions and people share very clever and concise solutions. Oh
>>
>>well, no big deal!
>>
>>
>>>>For simulation only, you could use a class instead, and then the 
>>>>class could provide its own to-string method - psdisplay() in VMM-speak.
>>>>And indeed, since we now have a full-fledged string data type, it's 
>>>>easy to provide a to-string function for any data type.
>>>>
>>>>I sometimes wonder whether there is any utility at all in unpacked 
>>>>structs.  They make little sense for synthesis, and for simulation 
>>>>it's surely better to use a class; the class can then have a pack 
>>>>method that converts the appropriate parts of its content into a 
>>>>packed struct suitable for injection into an RTL model.
>>>
>>>
>>>Interesting questions. Perhaps we could get the following three 
>>>committee members to respond:
>>>
>>>Matt Maidment from Intel, who has been using SV for synthesis for 3-4 
>>>years now.
>>>Brad Pierce (and Karen if she has time) on Synopsys' take on unpacked 
>>>structs for synthesis.
>>>Nikhil Rishiyur from the Bluespec synthesis perspective.
>>>
>>>Regards - Cliff
>>>
>>>
>>>
>>>
>>>>--
>>>>Jonathan Bromley, Consultant
>>>>
>>>>DOULOS - Developing Design Know-how
>>>>VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services
>>>>
>>>>Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 
>>>>1AW,
>>>
>>>UK
>>>
>>>
>>>
>>>>Tel: +44 (0)1425 471223                   Email:
>>>
>>>jonathan.bromley@doulos.com
>>>
>>>
>>>
>>>>Fax: +44 (0)1425 471573                           Web:
>>>
>>>http://www.doulos.com
>>>
>>>
>>>
>>>>This e-mail and any  attachments are  confidential and Doulos Ltd. 
>>>>reserves all rights of privilege in  respect thereof. It is intended 
>>>>for the use of the addressee only. If you are not the intended 
>>>>recipient please delete it from  your  system, any  use, disclosure, 
>>>>or copying  of this  document is unauthorised. The contents of this 
>>>>message may contain personal views which are not the views of Doulos 
>>>>Ltd.,
>>>
>>>unless specifically stated.
>>>
>>>----------------------------------------------------
>>>Cliff Cummings - Sunburst Design, Inc.
>>>14314 SW Allen Blvd., PMB 501, Beaverton, OR 97005
>>>Phone: 503-641-8446 / FAX: 503-641-8486 cliffc@sunburst-design.com / 
>>>www.sunburst-design.com Expert Verilog, SystemVerilog, Synthesis and 
>>>Verification Training
>>>
>>>
>>
>>
>>
> 
> 
Received on Tue Feb 28 10:55:48 2006

This archive was generated by hypermail 2.1.8 : Tue Feb 28 2006 - 10:56:21 PST